一、最常用匹配语法
- re.match(“正则表达式”, “字符串”) >>> 从头开始匹配
- re.search(“正则表达式”, “字符串”) >>> 匹配包含
- re.findall(“正则表达式”, “字符串”) >>> 把所有匹配到的字符放到列表中,返回列表
- re.split(“正则表达式”, “用来替换的字符串”, “字符串”, “替换次数(从左到右)”) >>> 以匹配到的字符当做列表分隔符
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5e7986fec50a41df83c5998e616f111e.png)
- re.sub 匹配字符并替换
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/81a5b10ad8941013fbf6b8e17b6c5ea8.png)
二、常用正则表达式符号
- ‘\n’:换行符匹配
- ‘\r’:匹配一个回车符
- ‘\v’:垂直制表符匹配(文本竖直时tab)
- ‘\t’:制表符匹配
- ‘\f’:匹配一个换页符
- ’ . ':默认匹配除\n之外的任意一个字符,若指定flag为re.S(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次
- ‘{n}’:n是非负整数,匹配前一个字符n次
- ‘{n, }’:n是非负整数,匹配n次或多次
- ‘{n,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’:匹配非数字
- [a-z]:匹配[a-z]小写字符
- [A-Z]:匹配[A-Z]大写字符
- [a-zA-Z]:匹配[a-zA-Z]大小写字符
- [^xyz]:反向字符集。匹配未包含的任何字符
- [^a-z]:反向范围字符集。匹配不在指定范围内的任意字符
- ‘\w’:匹配[A-Za-z0-9]
- ‘\W’:匹配非[A-Za-z0-9]
- ‘\s’:匹配空白字符、\t、\n、\r , re.search("\s+",“ab\tc1\n3”).group() 结果 ‘\t’
- ‘\S’:匹配任意非空白字符。等价于[^\f\n\r\t\v]
- ‘(?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’}
1. “^”和“$”作用
- 注意:针对整个字符串需要以" ^ “为开头,以” $ “为结尾,而不是指需要匹配的子串以” ^ “为开头,以” $ "为结尾,看如下例子;
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Mason
import re
if __name__ == '__main__':
name = "Hua123Juan456"
# search方法, 匹配包含, 正则表达式中包含"^"时, 才会从头开始匹配
print(re.search("^Juan", name))
print(re.search("Juan$", name))
print(re.search("^Hua.+6$", name))
# 输出:
None
None
<re.Match object; span=(0, 13), match='Hua123Juan456'>
2. 匹配时,只匹配首次匹配到的字符串就返回匹配位置信息,左闭右开区间
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Mason
import re
if __name__ == '__main__':
name = "Hua123Juan456"
# search方法, 匹配包含, 正则表达式中包含"^"时, 才会从头开始匹配
print(re.search("^J[a-z]+]", name))
print(re.search("J[a-z]+$", name))
print(re.search("J[a-z]+", "Hua123JuanJuan456"))
# 输出:
None
None
<re.Match object; span=(6, 10), match='Juan'>
3. "?"匹配字符串时,?只作用于“与其相邻的字符”,匹配时遵循贪心算法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Mason
import re
if __name__ == '__main__':
# search方法, 匹配包含, 正则表达式中包含"^"时, 才会从头开始匹配
print(re.search("aa?", "lexaaa"))
print(re.search("aa?", "alexaaa"))
print(re.search("aa?", "aalexaaa"))
print(re.search("aa?", "aaalexaaa"))
# 输出:
<re.Match object; span=(3, 5), match='aa'>
<re.Match object; span=(0, 1), match='a'>
<re.Match object; span=(0, 2), match='aa'>
<re.Match object; span=(0, 2), match='aa'>
4. ‘{m}’ 匹配前一个字符m次/’{n,m}’ 匹配前一个字符n到m次
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Mason
import re
if __name__ == '__main__':
name = "1Ma2s3on4567"
# search方法, 匹配包含, 正则表达式中包含"^"时, 才会从头开始匹配
print(re.search("[0-9]{3}", name))
print(re.search("[0-9]{1,3}", name))
print(re.findall("[0-9]{3}", name))
print(re.findall("[0-9]{1,3}", name))
# 输出:
<re.Match object; span=(8, 11), match='456'>
<re.Match object; span=(0, 1), match='1'>
['456']
['1', '2', '3', '456', '7']
5. ’ | ’ 匹配|左或|右的字符
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Mason
import re
if __name__ == '__main__':
name = "ABC12abc456"
print(re.search("abc|ABC", name).group())
print(re.findall("abc|ABC", name))
# 输出:
ABC
['ABC', 'abc']
6. ’ (…) ’ 分组匹配
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Mason
import re
if __name__ == '__main__':
name = "ABC12abccabcabc456"
print(re.search("(abc){2}", name))
print(re.search("abc{2}", name))
# 输出:
<re.Match object; span=(9, 15), match='abcabc'>
<re.Match object; span=(5, 9), match='abcc'>
7. 正则技巧(重要)
>>> re.search("(?P<id>[0-9]+)", "abc123dfg456").group("id")
'123'
>>> re.search("(?P<id>[0-9]+)", "abc123dfg456").groupdict()
{'id': '123'}
>>> re.search("(?P<id>[0-9]+)", "abc123dfg456").groupdict()["id"]
'123'
>>>
8. 正则匹配反斜杠时
- 反斜杠的困扰
与大多数编程语言相同,正则表达式里使用"\“作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符”\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\“表示。同样,匹配一个数字的”\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Mason
import re
if __name__ == '__main__':
name = "Mason\\"
print(re.search("\\\\", name))
print(re.search("\\\\", name).group())
print(re.findall("\\\\", name))
print(re.search(r"\\", name))
print(re.search(r"\\", name).group())
print(re.findall(r"\\", name))
# 输出:
<re.Match object; span=(5, 6), match='\\'>
\
['\\']
<re.Match object; span=(5, 6), match='\\'>
\
['\\']
9. 其他几个匹配模式
- re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/669db91baad398a26649c35f50725ef7.png)
- re.M(MULTILINE): 多行模式,改变’^‘和’$'的行为(参见上图)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9478b6985e05f199f9488593f7ba1671.png)
- S(DOTALL): 点任意匹配模式,改变’.'的行为
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1b44f45c3c51a7721338f59876ccda1e.png)
10. match和search区别
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Mason
import re
if __name__ == '__main__':
name = "Hua123Juan456"
# match方法, 从头开始匹配, 正则表达式中不论包不包含"^", 都会从头开始匹配
print(re.match("Juan", name))
print(re.match("^Juan", name))
# search方法, 匹配包含, 正则表达式中包含"^"时, 才会从头开始匹配
print(re.search("Juan", name))
print(re.search("^Juan", name))
# 输出:
None
None
<re.Match object; span=(6, 10), match='Juan'>
None