正则表达式
1️⃣ 正则表达式其实就是一个规则,我们根据这个规则去匹配字符串,得出我们需要的字符串就可以了。
2️⃣ 在python中,正则的使用都在re模块中
3️⃣ 我们需要了解如何写出符合的需求的正则表达式
常用的五种方法
下面我们会简单的介绍re模块中查找符合字符串的五种方法。这里需要特别说明一下,在正则规则中前面加个r,是为了防止转义字符!因此,在写正则规则时,我们最好都要加个r!
match
从头开始匹配,匹配到就返回符合规则的字符串,不符合规则的会返回None!
print(re.match(r'abc','abc')) print(re.match(r'abc','1abc'))
运行结果:
search
查找符合规则的字符串,如果有多个字符串符合对应的规则,那么就会返回第一个匹配到的字符串
print(re.search(r'abc', 'abc123abc200123abc'))
运行结果:
fullmatch
要求字符串从头到尾必须全都与对应的规则匹配上
print(re.fullmatch(r'a\d+c', 'a123456c')) print(re.fullmatch(r'a\d+c','a12wda3554c')) #不能从头到尾完全与规则相匹配
运行结果:
注:\d代表匹配一个数字字符,+是修饰\d的,表示的是一个或者多个数字,这个正则所要表达的就是匹配一个以a开始,中间至少有一个数字,以c为结尾的一个字符串,不能是子串!
findall
查找所有符合条件的字符串,并且以列表的形式返回匹配到的字符串!
print(re.findall(r'a\d+c', 'a123cwewdea325c'))
运行结果:
finditer
查找所有符合条件的字符串,并且返回一个迭代器对象,可以利用for循环遍历
x=re.finditer(r'a\d+c','a123cwewdea325c') for i in x: print(i)
运行结果:
总结:以上的匹配查找实质都是返回一个re.match的对象,并且我们可以利用dir函数查看并利用这个对象的属性与方法。我们将重点介绍group方法来获取对象中我们需要的内容
group方法
正则表达式可以利用()可以对查找的规则进行分组,我们所写出那个正则表达式默认就是group(),也就是group(0)。利用group方法就可以打印出符合条件的字符串了
实现的代码如下:
x=re.search(r'(a\d+)(b\d+)(c\d+)', 'a123b456c789') print(x.group()) //找出符合整个正则表达式的条件的字符串 print(x.group(1)) //在group(0)的基础上,根据分组1的规则查找符合的字符串,下同 print(x.group(2)) print(x.group(3))
运行结果如下:
图解分组:
下面我们变换一下代码:
x=re.search(r'(a\d+)(b\d+)c\d+', 'a123b456c789') print(x.group()) print(x.group(1)) print(x.group(2))
运行结果:
我们可以发现对c\d+没有进行分组后,对于group(1)和group(2)的查找是不会包含的未分组c\d+的内容,只有group()才可以找到!!!也就是说,group(数字)只会严格匹配符合分组规则的字符串。如果数字大于分组数量,那么运行结果会抛出异常!
groupdict方法
(?P<别名>规则)给分组起别名。groupdict以字典的形式返回,需要对分组取别名,相当于给一个键,与匹配到的字符串形成一个键值对!
代码如下:
x=re.search(r'(?P<test>a\d+)(b\d+)c\d+', 'a123b456c789') print(x.groupdict())
运行结果:
re.compile方法
将写好的正则规则编译,形成一个正则对象,然后再调用正则对象的方法。与之前的写法对比,写好一次正则规则,可以进行多次的使用!
代码如下:
#之前的 print(re.search(r'a\d+', 'a123b456c789a111')) #经过compile编译的 patter = re.compile(r'a\d+') print(patter.search('a123b456')) print(patter.search('a4564b456s2'))
运行结果:
正则修饰符
re.I 让规则不区分大小写
代码如下:
print(re.search(r'a\d+', 'A123b456c789', re.I))
运行结果:
re.S 可以匹配到换行符
print(re.findall(r'.','hello\nworld')) print(re.findall(r'.','hello\nworld',re.S))
运行结果:
re.M
正则表达式中的元字符
其中[ ]还可以表示范围例如:[0-9A-Za-z]等
^在[ ]中表示取反的意思,^还可以表示要匹配某一个字符开头的字符串,此时相当于match函数作用。
同理要是以某一字符结尾字符串最后加上了$符号,那么就是匹配以最后一个字符结尾的字符串!同时使用开头(^)与结尾元字符($),就相当于fullmatch作用!
|的使用,代码如下:
直接使用:
print(re.search(r'abc|1abc', 'abc55555')) print(re.search(r'abc|1abc', '1abc555555'))
运行结果:
结合分组()使用:
print(re.findall(r'u(23|67|34)x', 'u23xiu67xlu34x')) y = re.finditer(r'u(23|67|34)x','u23xiu67xlu34x') for i in y: print(i.group())
运行结果:
可以发现findall只会打印分组里面的内容,而利用finditer会记录下我们所需要的字符串
正则替换
利用正则表达式,利用re模块中的sub函数,来替换符合规则的字符串!
s1 = 'a12b34c56d78' print(re.sub(r'\d+', 'T', s1))
运行结果:
sub中有三个参数,第一个参数是替换的规则也就是正则表达式,第二个参数是要替换的内容(也可以利用函数进行替换),第三个参数就是目标字符串!
第二个参数是函数的代码如下(将数字乘以2替换回去):
s1 = 'a12b34c56d78' def test(x): data = x.group() return str(int(data)*2) print(re.sub(r'\d+',test,s1))
运行结果:
利用函数替换要注意以下几点:
1️⃣ 与平常调用函数不一样,这里是通过函数名不用带括号,并且编译器自动会帮我们传入re.match对象x
2️⃣ test函数返回值类型必须是字符串。在调用group函数返回得到的是一个字符串
贪婪模式和非贪婪模式
贪婪模式:尽可能多的匹配到符合条件的字符串
非贪婪模式:尽可能少的匹配到符合条件的字符串
可以通过下列代码进行理解
s2 = 'a123b456c789' x=re.search(r'b(.+)(\d+)',s2) print(x.group()) print(x.group(1)) print(x.group(2))
运行结果:
图解过程:
如果后面是\d*,那么后一个分组将会什么数据都没有了~~。如何解决这一问题呢?可以通过?(一般放在匹配范围符后面)
来将贪婪模式转换成为非贪婪模式!!!
s2 = 'a123b456c789' x=re.search(r'b(.+?)(\d+)',s2) print(x.group()) print(x.group(1)) print(x.group(2))
运行结果:
由于是非贪婪模式,那么就会尽可能少的匹配,所以group(1)就匹配1个字符串,后面满足\d+的只有两个数字,所以group()才会是b456,进一步的理解可以参考贪婪模式这篇文章!
以上就是关于正则表达式的基础内容理解,之后还需要自己多加练习,理解即可!