正则表达式
定义:正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。
1、正则概览
常用的正则表达式元字符:
‘.‘ # 默认匹配除\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|ABC","ABCBabcCD").group() 结果‘ABC‘ ‘(...)‘ # 分组匹配,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‘ ‘\b‘ # 匹配一个单词边界,也就是指单词和空格间的位置 ‘(?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\nld‘) 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 匹配任何空白字符;他相当于类[\t \n \r \f \b \v] # \S 匹配任何非空白字符;他相当于类[^ \t\n\r\f\v] # \w 匹配任何字母数字字符;他相当于类[a-z0-9A_Z] # \W 匹配任何非字母数字字符;他相当于类[^a-z0-9A_Z] # \b 匹配一个单词边界,也就是指单词和空格间的位置 # 匹配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\b‘, ‘helloI am a [email protected]!‘)) # [‘I‘, ‘I‘] print(re.findall(r‘\bI‘, ‘hello,Iss am a [email protected]!‘)) # [‘I‘] # \.: 转义通配符‘.‘为普通的‘.‘ print(re.search(‘a\.‘, ‘agj‘)) # None # \\: ret = re.findall("\\\\","abc\de") # [‘\\‘] print(ret) ret = re.findall(r"\bblow","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