本文共 4502 字,大约阅读时间需要 15 分钟。
正则表达式是NLP中的基本应用。正则表达式是一种定义了搜索模式的特征序列,主要用于字符串的模式匹配,或是字符的匹配。re模块是操作正则表达式的模块。
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
re.match(pattern, string, flags=0)# re.match( <正则表达式> , <需要匹配的字符串> ) 需要匹配的字符串> 正则表达式>
参数 | 描述 |
---|---|
pattern | 匹配的正则表达式 |
string | 要匹配的字符串。 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志 |
匹配成功re.match方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。匹配对象方法 | 描述 |
---|---|
group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups() | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
import reprint(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
注意:
import reline = "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 dogsmatchObj.group(1) : CatsmatchObj.group(2) : smartermatchObj.groups() : ('Cats', 'smarter')
匹配符号 | 匹配含义 |
---|---|
. | 匹配任意1个字符(除了\n,可以使用re.S包含\n) |
[ ] | 匹配[]中列举的字符 |
\d | 匹配数字,即0-9 |
\D | 匹配非数字,即不是数字 |
\s | 匹配空白,即空格,tab键 |
\S | 匹配非空白 |
\w | 匹配非空白,即a-z,A-Z,0-9,_,汉字 |
\W | 匹配特殊字符,即非字母,非数字,非汉字 |
注意:
匹配符号 | 匹配含义 |
---|---|
* | 匹配前一个字符出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出现1次或者无限次,即至少有1次 |
? | 匹配前一个字符出现1次或者0次,即要么有1次,要么没有 |
{m} | 匹配前一个字符出现m次 |
{m,n} | 匹配前一个字符出现从m到n次 |
注意:
此处可以体现出正则表达式的贪婪特性,在同等条件下,会自动使*、+、?、{1,5}匹配多的字符,取消贪婪特性可使用*?、 +?、 ??、 {}?在表达式中若有^代表匹配内容的首字符应该与正则表达式中的首字符匹配,否则无输出。
在表达式中若有$代表匹配内容的末字符应该与正则表达式中的末字符匹配,否则无输出。匹配符号 | 匹配含义 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
[^指定字符]: 表示除了指定字符都匹配# [^>]*> 表示 只要不是 字符> 就可以匹配多个,直到遇到># | 在此处表示 并re.sub(r'<[^>]*>|\s| ','',strs) # 表示将strs中在匹配到的字符替换成无,并输出替换后的strs
匹配符号 | 匹配含义 |
---|---|
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串 |
(?P) | 分组其别名 |
(?P=name) | 引用别名为name分组匹配到的字符串 |
与match的区别为:不从开头开始匹配,在文中寻找匹配项,只查找一次
import re# 根据正则表达式查找数据,注意:只查找一次match_obj = re.search("\d+","水果有20个,其中苹果10个.")if match_obj: # 获取匹配结果数据 print(match_obj.group())else: print("匹配失败")#---output-----20
与search基本相同,但可以查找多次
import re# 根据正则表达式查找数据,注意:只查找一次result = re.findall("\d+","水果有20个,其中苹果10个.")print(result)# ---output------['20', '10']
import re # count=0 替换次数,默认全部替换,count=1根据指定次数替换result = re.sub("\d+","2","评论数:10,点赞数:20",count=1)print(result)# ---output------评论数:2,点赞数:20
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
根据匹配进行切割字符串,并返回一个列表
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
解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,这样“?”前面的正则表达式不能匹配“?”后面正则表达式的数据
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]+)>.* ", "hh")if match_obj: print(match_obj.group()) print(match_obj.group(1)) print(match_obj.groups())else: print("匹配失败")# ---output------hhhtml('html',)
转载地址:http://jvili.baihongyu.com/