正则表达式
定义:正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。
1、正则概览
常用的正则表达式元字符:
'.' # 默认匹配除 之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' # 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a"," abc eee",flags=re.MULTILINE) '$' # 匹配字符结尾,或e.search("foo$","bfoo sdfsf",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|ABC","ABCBabcCD").group() 结果'ABC' '(...)' # 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c 'A' # 只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的 '' # 匹配字符结尾,同$ 'd' # 匹配数字0-9 'D' # 匹配非数字 'w' # 匹配[A-Za-z0-9] 'W' # 匹配非[A-Za-z0-9] 's' # 匹配空白字符、 、 、 , re.search("s+","ab c1 3").group() 结果 ' ' '' # 匹配一个单词边界,也就是指单词和空格间的位置 '(?P<name>...)' # 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
常用的匹配语法:
re.findall() # 所有的解雇odour返回在一个列表里边 re.search() # 返回一个对象(oobject),返回匹配到的第一个对象,对象可以调用group方法哪去返回结果 re.match() # 只在字符串开始匹配,返回匹配到的第一个对象,对象可以调用group方法哪去返回结果 re.split() # 分割,先第一个参数进行分割,再第二个参数分割 re.sub() # 替换('寻找的规则', '替换后的内容', '需要替换的字符串') re.compile() # 当需要多次匹配方法的时候,compilce可以将正则便宜为正则对象,之后再进行调用
2、元字符用例
.: 通配符,代之所有字符,一个'.'代指一个(除了换行符)
import re
ret = re.findall('w..l', 'hello world') print(ret) # ['worl'] ret = re.findall('w..l', 'hello w ld') print(ret) # []
^: 尖角符,必须是最开始的
import re ret = re.findall('^h...o', 'hdasdhello') print(ret) # []
$:匹配结尾的
import re
ret = re.findall('h...o$', 'asshessosadgg') print(ret) # []
*: 重复匹配(0-n次),下例子为重复匹配a和'.',0次也可以匹配出来
import re ret = re.findall('b*$', 'aaaawangaaaaajiebbbbbb') print(ret) ret = re.findall('wang.*jie', 'aaaawangaaaaajieaaaaa') print(ret)
+: 重复匹配(1-n次),匹配1到无穷的b
import re ret = re.findall('b+', 'aaaawangaaaaajiebbbbbb') print(ret) # ['bbbbbb'] ret = re.findall('a+b', 'aaaawangaaaaajieaaaabbbbbb') print(ret) # ['aaaab'] ret = re.findall('a+b+', 'aaaawangaaaaajieaaaabbbbbb') print(ret) # ['aaaabbbbbb']
?: 闭区间的[0,1]
import re ret = re.findall('a?b', 'aaaawangaaaaajieaaaabbbbbb') print(ret) # ['ab', 'b', 'b', 'b', 'b', 'b']
{}: 下例为匹配5个a和一个b, 匹配1到三个a和一个b,默认为贪婪匹配,默认最大的
import re ret = re.findall('a{5}b', 'aaaaab') print(ret) # ['aaaaab'] ret = re.findall('a{1,3}b', 'aaaab') print(ret) # ['aaab']
结论:推荐使用前者
* = {0,正无穷} = {0,}
+ = {1,正无穷} = {1,}
? = {0,1}
[]: []内为或的关系,所以第一个例子中com分别为三个字符‘c’,‘o’,‘m’,所以只能匹配到c
import re ret = re.findall('baidu.[com]', 'testbaidu.comtest') print(ret) # ['baidu.c'] ret = re.findall('[a-z]', 'adx') print(ret) # ['a', 'd', 'x']
如果想要匹配到整个的com,请看如下方法:
import re obj = re.compile('.com') print(obj.findall('baidu.com.cn')) # ['.com'] print(obj.findall('qq.com')) # ['.com']
[]: 取消元字符的特殊功能,三个例外( ^ -)
import re ret = re.findall('[w,*,.]', 'aw*tes.t,') print(ret) # ['w', '*', '.', ','] ret = re.findall('[1-9,a-z,A_Z]', '12t-yA_S') print(ret) # ['1', '2', 't', 'y', 'A', '_']
^放在中括号中为取反的意思,取反的范围为中括号内的所有内容
import re ret = re.findall('[^t]', '12tyAS') print(ret) # ['1', '2', 'y', 'A', 'S']
:反斜杠后边跟元字符能去除其特殊功能,反斜杠后边跟普通字符能实现其特殊功能
import re # d 匹配任何十进制数;相当于类[0-9] # D 匹配任何非数字字符;相当于类[^0-9] # s 匹配任何空白字符;他相当于类[ f v] # S 匹配任何非空白字符;他相当于类[^ fv] # w 匹配任何字母数字字符;他相当于类[a-z0-9A_Z] # W 匹配任何非字母数字字符;他相当于类[^a-z0-9A_Z] # 匹配一个单词边界,也就是指单词和空格间的位置 # 匹配11和数字 print(re.findall('d{11}', 'testabcdef23456112345123123213678333')) # ['23456112345', '12312321367'] # 匹配空格+asd print(re.findall('sasd', 'ahs asd dsa')) # [' asd'] # 匹配任意字符+asd print(re.findall('wasd', 'ahsasddsa')) # 用来捕捉边界,捕捉的前后位置(与任何特殊字符的边界) print(re.findall(r'I', 'helloI am a LI@ST!')) # ['I', 'I'] print(re.findall(r'I', 'hello,Iss am a LI@ST!')) # ['I'] # .: 转义通配符'.'为普通的'.' print(re.search('a.', 'agj')) # None # \: ret = re.findall("\\","abcde") # ['\'] print(ret) ret = re.findall(r"blow","blow") # ['blow'] print(ret)
():分组
import re print(re.findall('(as)+', 'testasasdfs')) # ['as'] print(re.search('(as)+', 'adfdasas').group()) # asas
3、正则表达式的方法
表达式的几种方法:
import re # re.findall() # 所有的解雇odour返回在一个列表里边 # re.search() # 返回一个对象(oobject),返回匹配到的第一个对象,对象可以调用group方法哪去返回结果 # re.match() # 只在字符串开始匹配,返回匹配到的第一个对象,对象可以调用group方法返回结果 # re.split() # 分割,先第一个参数进行分割,再第二个参数分割 # re.sub() # 替换('寻找的规则', '替换后的内容', '需要替换的字符串') # re.compile() # 当需要多次匹配方法的时候,compilce可以将正则便宜为正则对象,之后再进行调用 ret = re.match('asd', 'fjdasdasd') print(ret) # None ret = re.match('asd', 'asdfdjasd') print(ret.group()) # asd ret = re.split('[g, s]', 'fdgsdasd') print(ret) # ['fd', '', 'da', 'd'] ret = re.split('[j, s]', 'sdjksal') print(ret) # ['', 'd', 'k', 'al'] ret = re.sub('w..g', 'test', 'sadasfwangsdasd') print(ret) # sadasftestsdasd
4、正则的特殊用法
import re ret = re.search('(?P<id>d{3})/(?P<name>w{3})', 'weeew34ttt123/ooo') print(ret.group()) # 123/ooo print(ret.group('id')) # 123 print(ret.group('name')) # ooo