re模块用来使用正则表达式。正则表达式用来对字符串进行搜索的工作。我们最应该掌握正则表达式的查询,更改,删除的功能。特别是做爬虫的时候,re模块就显得格外重要。
1.查询
1 import re 2 a = re.match("abc","aabccc") 3 b = re.search("abc","aabcc") 4 print("a =",a) 5 print("b =",b)
运行结果: a = None b = <_sre.SRE_Match object; span=(1, 4), match='abc'>
re.match是从字符串开头开始匹配,如果和匹配字符不同,即便字符串内包含相同内容,返回值也为空。而re.search是匹配字符串内,只要字符串内包含被搜索内容,就有返回值。
这里,查询的结论是无的话,返回值就是None。我们可以把它和if或者while等循环配合起来使用,如果需要调用搜寻结果,需要在返回值后加.group()。
1 a = ["abcdef","aaccd","aadfa","adffadsfabc"] 2 for i in a: 3 if re.search("abc",i): 4 print("%s内包含:%s"%(i,re.search("abc",i).group()))
运行结果:
abcdef内包含:abc
adffadsfabc内包含:abc
还有一种查询方法
1 a = "123456789aaa123aaa654" 2 print(re.findall("aaa",a))
运行结果: ['aaa', 'aaa']
re.findall就是把字符串内所有的关键字都搜索出来生成列表输出。
2.更改
1 a = "123456789aaa123aaa654" 2 print("全部更改:",re.sub("aaa","bbb",a)) 3 print("更改指定次数:",re.sub("aaa","bbb",a,count=1)) 4 print("删除搜索内容:",re.sub("aaa","",a))
运行结果: 全部更改: 123456789bbb123bbb654 更改指定次数: 123456789bbb123aaa654 删除搜索内容: 123456789123654
用re.sub可以对对字符串进行更改或删除的操作。注意re.sub后没有.group()的用法。
此外还有一个分割的用法:
1 a = "123456789aaa123aaa654" 2 print(re.split("aaa",a))
运行结果: ['123456789', '123', '654']
将原字符串按照搜索的关键字分割成一个列表输出。
分 割 线
掌握了最基础的语法后,我们要了解一下较为复杂的正则表达式的使用方法了:
首先,我们要先了解正则表达式的表达符号
'.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) '$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以 '*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a'] '+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb'] '?' 匹配前一个字符1次或0次 '{m}' 匹配前一个字符m次 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb'] '|' 匹配|左或|右的字符,匹配到先出现的就停止。 '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
还有一些搜索方式
'\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的 '\Z' 匹配字符结尾,同$ '\d' 匹配数字0-9 '\D' 匹配非数字 '\w' 匹配[A-Za-z0-9] '\W' 匹配非[A-Za-z0-9] 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t' '(?P<name>...)' 分组匹配
(?P<name>...)分组匹配:相当于每个关键字前加一个key生成一个字典,比方我们要匹配一个身份证号,匹配规则是前六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
1 ID = "410110199912121234" 2 a = re.search("(?P<address>[0-9]{6})(?P<birthday>[0-9]{8})(?P<order>[0-9]{3})(?P<check>[0-9]{1})",ID).groupdict() 3 print(a)
运行结果: {'address': '410110', 'birthday': '19991212', 'order': '123', 'check': '4'}
现在,我们可以举个栗子吧了:我们想做一个加法计算器,第一步就是要把两个计算的加数搜索出来,最简单的方式是这样:
1 import re 2 cul = "123+456" 3 a = re.search("\d+[+]",cul).group()[:-1] 4 b = re.search("[+]\d+",cul).group()[1:] 5 print("a = %s,b = %s"%(a,b))
运行结果: a = 123,b = 456
我们在返回值里用了切片的方法,删除了返回值中的加号“+”。
这时候再想一想:要是a或b之间有小数点怎么办?用这样的方法就不行了吧!我们把cul赋值为"1.23+3.45"运行一下:
运行结果:
a = 23,b = 4
明显不对了,怎么办呢?需要把小数点也加进去
1 import re 2 cul = "1.23+4.56" 3 a = re.search("\d+[.]\d+[+]",cul).group()[:-1] 4 b = re.search("[+]\d+[.]\d+",cul).group()[1:] 5 print("a = %s,b = %s"%(a,b))
运行结果: a = 1.23,b = 4.56
可是还有个问题,小数点不是每次都有啊,怎么让它自己判断呢?可以加个”?“
1 import re 2 def add(cul): 3 a = re.search("(\d+)?[.]?\d+[+]",cul).group()[:-1] 4 b = re.search("[+]\d+[.]?(\d+)?",cul).group()[1:] 5 print("a = %s,b = %s"%(a,b)) 6 add("1.23+4.56") 7 add("123+456")
运行结果:
add("1.23+4.56") add("123+456")
这里有个很关键的问题:
正则表达式中的字符采用的是转义字符,如果需要匹配的字符为"aa\\bb\\cc"时,每个"\"前都须加一个"\",就成了"aa\\\\bb\\\\cc"在匹配字符串内有”+“、”*“时都需要加上反斜杠。我们可以把匹配的字符串前加"r",就可以不用在每个"\"前都再加上"\",程序也更加直观。
此外,我们还可以把变量套进正则表达式中
1 import re 2 ans = "2" 3 cul = "(6-4)*2" 4 cul2 = "6-4" 5 print("简化后:",re.sub("[(]%s[)]"%cul2,ans,cul))#匹配的表达式为一个变量
运行结果: 简化后: 2*2
但这里要注意一下:如果表达式内有加号或乘号时是不能这样使用的,即便在表达式前加"r"也不行,必须把+换成\+
1 import re 2 ans = "10" 3 cul = "(6+4)*2" 4 cul2 = "6\+4" #这个地方的+或*必须用\+或\* 5 print("简化后:",re.sub("[(]%s[)]"%cul2,ans,cul))
运行结果: 简化后: 10*2
还有一些更复杂的方法,需要我们慢慢研究吧!