正则表达式是NLP中的基本应用。正则表达式是一种定义了搜索模式的特征序列,主要用于字符串的模式匹配,或是字符的匹配。re模块是操作正则表达式的模块。
一,re.match匹配
1,re.match的用法
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
a)函数语法
re.match(pattern, string, flags=0)
# re.match(<正则表达式>,<需要匹配的字符串>)
b)函数参数说明
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串。 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志 |
c)返回匹配对象
匹配成功re.match方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法 | 描述 |
group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups() | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
2,re.match的实例
a)实例1
import re
print(re.match('www', 'www.runoob.com')) # 在起始位置匹配
print(re.match('www', 'www.runoob.com').group()) # 返回匹配到的内容
print(re.match('www', 'www.runoob.com').span()) # 返回匹配到的内容在文本的索引
print(re.match('com', 'www.runoob.com'))
# ---output-----
<_sre.SRE_Match object; span=(0, 3), match='www'>
www
(0, 3)
None
注意:
- 返回的match对象使用span()方法将返回匹配索引。
- 如若没有匹配到结果,将返回None
b)实例2
import re
line = "Cats are smarter than dogs"
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print ("matchObj.group() : ", matchObj.group())
print ("matchObj.group(1) : ", matchObj.group(1))
print ("matchObj.group(2) : ", matchObj.group(2))
print ("matchObj.groups() : ", matchObj.groups())
else:
print ("No match!!")
# ---output------------
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter
matchObj.groups() : ('Cats', 'smarter')
二,正则表达式模式
1,匹配单个字符
匹配符号 | 匹配含义 |
. | 匹配任意1个字符(除了\n,可以使用re.S包含\n) |
[ ] | 匹配[]中列举的字符 |
\d | 匹配数字,即0-9 |
\D | 匹配非数字,即不是数字 |
\s | 匹配空白,即空格,tab键 |
\S | 匹配非空白 |
\w | 匹配非空白,即a-z,A-Z,0-9,_,汉字 |
\W | 匹配特殊字符,即非字母,非数字,非汉字 |
注意:
- ’ . '可以匹配除了 \n 的唯一字符,若想要匹配\n,可在正则表达式后加上re.S .
- \w 还可以匹配多种语言,所以需要慎用。
- \s 可以匹配到 \n
- [ ]中匹配10个数字可用[0-9],26个字母可用[a-z]
- [ ]中匹配除了指定字符以外都匹配:[^abcde]
2,匹配多个字符
匹配符号 | 匹配含义 |
* | 匹配前一个字符出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出现1次或者无限次,即至少有1次 |
? | 匹配前一个字符出现1次或者0次,即要么有1次,要么没有 |
{m} | 匹配前一个字符出现m次 |
{m,n} | 匹配前一个字符出现从m到n次 |
注意:
此处可以体现出正则表达式的贪婪特性,在同等条件下,会自动使*、+、?、{1,5}匹配多的字符,取消贪婪特性可使用*?、 +?、 ??、 {}?
3,匹配开头和结尾、除了指定字符都匹配
a)匹配开头和结尾
在表达式中若有^代表匹配内容的首字符应该与正则表达式中的首字符匹配,否则无输出。
在表达式中若有$代表匹配内容的末字符应该与正则表达式中的末字符匹配,否则无输出。
匹配符号 | 匹配含义 |
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
b)除了指定字符都匹配
[^指定字符]: 表示除了指定字符都匹配
# [^>]*> 表示 只要不是 字符> 就可以匹配多个,直到遇到>
# | 在此处表示 并
re.sub(r'<[^>]*>|\s| ','',strs) # 表示将strs中在匹配到的字符替换成无,并输出替换后的strs
4,匹配分组
- 字符‘|’ 在此处表示 或 ,由括号()来限定或的范围
- ()中的字符作为分组,group(num)中的num指定取出哪个分组
- \num 在正则表达式中引用分组num匹配到的字符
- (?P)分组起别名 (?P=name)引用别名为name分组匹配到的字符串
匹配符号 | 匹配含义 |
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串 |
(?P) | 分组其别名 |
(?P=name) | 引用别名为name分组匹配到的字符串 |
三,re.search匹配
与match的区别为:不从开头开始匹配,在文中寻找匹配项,只查找一次
import re
# 根据正则表达式查找数据,注意:只查找一次
match_obj = re.search("\d+","水果有20个,其中苹果10个.")
if match_obj:
# 获取匹配结果数据
print(match_obj.group())
else:
print("匹配失败")
#---output-----
20
四,re.findall匹配
与search基本相同,但可以查找多次
import re
# 根据正则表达式查找数据,注意:只查找一次
result = re.findall("\d+","水果有20个,其中苹果10个.")
print(result)
# ---output------
['20', '10']
五,re.sub 将匹配到的数据进行替换
1,使用字符串进行替换
import re
# count=0 替换次数,默认全部替换,count=1根据指定次数替换
result = re.sub("\d+","2","评论数:10,点赞数:20",count=1)
print(result)
# ---output------
评论数:2,点赞数:20
2,使用函数进行替换
import re
# match_obj:该参数系统自动传入
def add(match_obj):
# 获取匹配结果的数据
value = match_obj.group()
result = int(value) + 1
# 返回值必须是字符串类型
return str(result)
result = re.sub("\d+",add,"阅读数:10")
print(result)
# ---output-----
阅读数:11
六,re.split(| 表示 并)
根据匹配进行切割字符串,并返回一个列表
import re
ret = re.split(r":| ",'info:xiaozhang 33 shangdong')
print(ret)
# ---output----
['info', 'xiaozhang', '33', 'shangdong']
七,贪婪与非贪婪
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
import re
s = "This is a number 234-235-22-423"
r = re.match(".+(\d+-\d+-\d+-\d+)",s)
print(r.group(1))
#---output------
4-235-22-423
正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。
import re
s = "This is a number 234-235-22-423"
r = re.match(".+?(\d+-\d+-\d+-\d+)",s)
print(r.group(1))
#---output------
234-235-22-423
解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,这样“?”前面的正则表达式不能匹配“?”后面正则表达式的数据
八,r的作用
- Python中字符串前面加上 r 表示原生字符串,数据里面的反斜杠不需要进行转义,针对的只是反斜杠。
- Python里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
- 建议: 如果使用使用正则表达式匹配数据可以都加上r,要注意r针对的只是反斜杠起作用,不需要对其进行转义
match_obj = re.search('e\\\\/','''i have one nee\/dle''')
match_obj.group()
#---output----
'e\\/'
import re
match_obj = re.match(r"<([a-zA-Z1-9]+)>.*</\1>", "<html>hh</html>")
if match_obj:
print(match_obj.group())
print(match_obj.group(1))
print(match_obj.groups())
else:
print("匹配失败")
# ---output------
<html>hh</html>
html
('html',)