没有女朋友?点击查看追女生秘籍:https://blog.csdn.net/weixin_48448842/article/details/119630331
Python 正则表达式
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
Python 自 1.5 版本起增加了 re 模块,它提供 Perl 风格的正则表达式模式。
re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
本章节主要介绍 Python 中常用的正则表达式处理函数。
文章目录
re 正则表达式匹配
re.match 在起始位置匹配
re.match 尝试从字符串的起始位置匹配一个模式。
函数语法:
re.match(pattern, string, flags=0)
参数说明:
参数 | 说明 |
---|---|
pattern | 匹配的正则表达式 |
string | 待匹配的字符串 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。 |
若在起始位置匹配成功,返回 re.Match 对象。若不成功,则返回 None。
re.Match 对象:点击查看文末解释。
标志位:点击查看文末解释。
返回的匹配对象的对象方法:
re.Match 匹配对象方法 | 说明 |
---|---|
group(group=0) | 1. 返回匹配到的字符串。 2. 若指定 group,则返回指定的分组 |
groups() | 返回一个元组,包含所有分组 |
start(group=0) end(group=0) | 1. 返回匹配到的字符串的起始或结束位置。 2. 若指定 group,则返回指定的分组的起始或结束位置 |
span(group=0) | 1. 返回一个二项元组,包含匹配到的字符串开始、结束的位置 相当于 (start(group),end(group)) 2. 若指定 group,则返回指定分组的位置 |
示例 1:
>>> s = 'David 612 - Python'
>>> r = re.match(r'(.+) (\d+)',s) # 在表达式中,用小括号()括起来的即为分组
>>> r # 函数返回的是 re.Match 对象
<re.Match object; span=(0, 9), match='David 612'>
>>> r.group() # 返回匹配到的字符串
'David 612'
>>> r.group(1) # 返回第一个分组,分组的第一个下标为1,而不是0
'David'
>>> r.groups() # 返回所有分组
('David', '612')
>>> r.span() # 返回匹配到的字符串位置
(0, 9)
>>> r.span(2) # 返回第二个分组的位置
(6, 9)
开始位置:字符串第一个字符的下标
结束位置:字符串最后一个字符的下标 +1
示例 2:
>>> s = 'Python'
>>> re.match('PyPy',s)
None
re.fullmatch 匹配整个字符串
与 re.match 类似,但是是匹配整个字符串。
re.search 搜索整个字符串
re.search() 扫描整个字符串并返回第一个成功的匹配。
函数语法:
re.search(pattern, string, flags=0)
参数说明:
参数 | 说明 |
---|---|
pattern | 匹配的正则表达式 |
string | 待匹配的字符串 |
flags | 标志位,用于控制正则表达式的匹配方式 |
若匹配成功,返回 re.Match 对象。若不成功,则返回 None。
re.sub 替换
re.sub 用于替换字符串中的匹配项。
函数语法:
re.sub(pattern, repl, string, count=0, flags=0)
参数说明:
参数 | 说明 |
---|---|
pattern | 正则中的模式字符串 |
repl | 替换的字符串,也可为一个函数 |
string | 待替换的字符串 |
count | 替换的最大次数,默认 0 表示替换所有 |
flags | 编译时用的匹配模式,数字形式 |
若匹配成功,则返回替换后的字符串。
>>> s = 'Python2.2.4'
>>> re.sub('\d','3',s) # 将所有数字替换为3
'Python3.3.3'
repl 可以为一个函数。示例:
>>> s = 'Python2'
>>> f = lambda m:str(int(m.group(1))+1)
>>> re.sub(r'(\d)',f,s) # 将所有匹配到的数字+1
'Python3'
re.split 切割
re.split 按照能够匹配的子串将字符串分割后返回列表。
函数语法:
re.split(pattern, string[, maxsplit=0, flags=0])
参数说明:
参数 | 说明 |
---|---|
pattern | 匹配的正则表达式 |
string | 待匹配的字符串 |
maxsplit | 分隔次数,默认为 0,不限制次数 |
flags | 标志位,用于控制正则表达式的匹配方式 |
该函数返回一个列表。
示例:
>>> s = 'Python1,Python2,Python3'
>>> re.split(r'\d',s) # 以数字切割
['Python', ',Python', ',Python', '']
re.findall 查找所有
匹配正则表达式所匹配的所有子符串。
函数语法:
re.findall(pattern, string, flags=0)
参数说明:
参数 | 说明 |
---|---|
pattern | 匹配的正则表达式 |
string | 待匹配的字符串 |
flags | 标志位,用于控制正则表达式的匹配方式 |
在字符串中找到正则表达式所匹配的所有子符串,返回一个列表,包含匹配到的所有字符串。
若匹配的正则表达式中含分组,则只会返回分组内容。
如果没有找到匹配的,则返回空列表。
示例:
>>> s = 'Python1,Python2,Python3'
>>> re.findall(r'\d',s)
['1', '2', '3'] # 返回匹配到的所有字符串
>>> re.findall('a',s)
[] # 无匹配项,返回空列表
注意: match 和 search 是匹配一次,而 findall 匹配所有。
re.finditer 查找所有并返回迭代器
和 re.findall 类似,在字符串中找到正则表达式所匹配的所有字符串,并把它们作为一个迭代器返回。
函数语法:
re.finditer(pattern, string, flags=0)
re.finditer 返回的是 迭代器,包含匹配的 re.Match 对象 而不是字符串。
>>> re.finditer(r'\d',s)
<callable_iterator object at 0x01C91898>
>>> r = re.finditer(r'\d',s)
>>> r
<callable_iterator object at 0x01C918C8>
>>> for t in r:
print(t)
print(t.group)
<re.Match object; span=(6, 7), match='1'>
<built-in method group of re.Match object at 0x01CABA68>
<re.Match object; span=(14, 15), match='2'>
<built-in method group of re.Match object at 0x01C763A0>
<re.Match object; span=(22, 23), match='3'>
<built-in method group of re.Match object at 0x01CABA68>
re.compile 生成表达式对象
re.compile 函数用于编译正则表达式,生成一个正则表达式(re.Regex)对象,供 match 和 search 等函数使用。
re.Regex 对象:文末解释,点击跳转,或点击上方蓝色超链接跳转。
函数语法:
re.compile(pattern[, flags])
参数说明:
参数 | 说明 |
---|---|
pattern | 字符串形式的正则表达式 |
flags | 标志位,用于控制正则表达式的匹配方式 |
示例:
>>> p = re.compile(r'\d')
>>> s = 'Python1,Python2,Python3'
>>> p.match(s,pos=0,endpos=20) # 从第一个开始匹配,不匹配,返回 None
None
# pos 为开始匹配的位置,默认为 0,
# endpos 为结束匹配的位置,默认为字符串总长
# 这两个参数只有在 re.Regex 对象的方法才有,即用 re.compile 生成的对象
>>> p.match(s,6,20) # 从第六个开始匹配,匹配成功,返回 re.Match 对象
<re.Match object; span=(6, 7), match='1'>
>>> p.search(s,0,10)
<re.Match object; span=(6, 7), match='1'>
>>> p.findall(s,0,30)
['1', '2', '3']
>>> p.finditer(s,0,30)
<callable_iterator object at 0x01C14610>
>>> p.sub('5',s)
'Python5,Python5,Python5'
>>> p.split(s)
['Python', ',Python', ',Python', '']
re 对象
re.Match 对象
对象方法:
re.Match 匹配对象方法 | 说明 |
---|---|
group(group=0) | 1. 返回匹配到的字符串。 2. 若指定 group,则返回指定的分组 |
groups() | 返回一个元组,包含所有分组 |
start(group=0) end(group=0) | 1. 返回匹配到的字符串的起始或结束位置。 2. 若指定 group,则返回指定的分组的起始或结束位置 |
span(group=0) | 1. 返回一个二项元组,包含匹配到的字符串开始、结束的位置 相当于 (start(group),end(group)) 2. 若指定 group,则返回指定分组的位置 |
示例:
>>> s = 'David 612 - Python'
>>> r = re.search(r'(\d+).*(P)',s)
>>> r
<re.Match object; span=(6, 13), match='612 - P'> # 返回 re.Match 对象
>>> r.group() # 获取匹配到的字符串
'612 - P'
>>> r.group(1) # 获取第一个分组
'612'
>>> r.groups() # 获取所有分组
('612', 'P')
>>> r.start() # 获取字符串开始位置
6
>>> r.start(1) # 获取第一个分组开始位置
6
>>> r.end() # 获取字符串结束位置
13
>>> r.end(1) # 获取第一个分组结束位置
9
# 获取字符串位置
>>> r.span()
(6, 13)
>>> (r.start(),r.end())
(6, 13)
# 获取第二个分组的位置
>>> r.span(2)
(12, 13)
>>> (r.start(2),r.end(2))
(12, 13)
re.Regex 对象
re.compile 生成的对象,供 match 和 search 等函数使用。
re 修饰符 - 可选标志
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。
修饰符被指定为一个可选的标志。
多个标志可以通过按位 OR(|) 它们来指定。
如 re.I | re.M 被设置成 I 和 M 标志
修饰符 | 说明 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 “ . “ 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
示例:
>>> s = '''
DaViD 612
PyThOn
'''
>>> re.search(r'python',s,flags=re.I)
<re.Match object; span=(11, 17), match='PyThOn'>
>>> re.search(r'david \d+.python',s,flags=re.I | re.S)
<re.Match object; span=(1, 17), match='DaViD 612\nPyThOn'>
re 匹配模式(特殊字符)
模式字符串使用特殊的语法来表示一个正则表达式。
字母和数字表示他们自身;多数字母和数字前加一个反斜杠时会拥有不同的含义。
一些标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。
反斜杠本身需要使用反斜杠转义。
如果使用模式同时提供了可选的标志参数,某些模式元素的含义会改变。
基本
模式 | 说明 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾 |
. | 匹配除换行符外任意字符 当 re.DOTALL 标记被指定时,则可匹配包括换行符的任意字符。 |
…* | 匹配 0 个或多个的表达式 |
…+ | 匹配 1 个或多个的表达式 |
…? | 匹配 0 个或 1 个由前面的正则表达式定义的片段 非贪婪方式 |
a|b | 匹配 a 或 b |
*?、+?、?? | 匹配 re、re+、re? 的尽量少个* 非贪婪方式 |
[…] | 匹配 [] 中的任意一个字符 如 [amk] 匹配 ‘a’,‘m’或’k’ |
[^…] | 匹配不在 [] 中的字符 如:[^abc] 匹配除了 a, b, c 之外的字符。 |
…{n} | 匹配 n 个前面表达式 如,o{2} 不能匹配 Bob 中的 o,但是能匹配 food 中的两个 o。 |
…{n,} | 匹配 n 个及以上前面表达式 如,o{2,} 不能匹配 Bob 中的 o,但能匹配 foooood 中的所有 o。 o{1,} 等价于 o+。o{0,} 则等价于 o*。 |
…{n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
(?>…) | 匹配的独立模式,省去回溯 |
(?#…) | 注释 |
组
模式 | 说明 |
---|---|
(…) | 匹配括号内的表达式,也表示一个组 |
(?P…) | 命名的组 |
(?P=name) | 调用已命名的组 |
\1…\9 | 调用第 n 个分组的内容。 |
\10 | 匹配第 n 个分组的内容 如果它经匹配。否则指的是八进制字符码的表达式。 |
(?imx: …) | 在括号中使用i, m, 或 x 可选标志 只影响括号中的区域 |
(?-imx: …) | 在括号中不使用i, m, 或 x 可选标志 只影响括号中的区域 |
(?: …) | 类似 (…),但是不表示一个组 |
界定符
模式 | 说明 |
---|---|
(?<=…) | 前向肯定界定符 如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。 但一旦所含表达式已经尝试,匹配引擎根本没有提高; 模式的剩余部分还要尝试界定符的右边。 |
(?<!..) | 前向否定界定符 与肯定界定符相反,当所含表达式不能在字符串当前位置匹配时成功。 |
(?=…) | 后向肯定界定符 |
(?!..) | 后向否定界定符 |
转义字符
模式 | 说明 |
---|---|
\w | 匹配数字字母下划线 等价于 [A-Za-z0-9_] |
\W | 匹配非数字字母下划线 等价于 [^A-Za-z0-9_] |
\s | 匹配任意空白字符 等价于 [ \t\n\r\f\v] |
\S | 匹配任意非空字符 等价于 [^ \t\n\r\f\v] |
\d | 匹配任意数字 等价于 [0-9] |
\D | 匹配任意非数字 等价于 [^0-9] |
\A | 匹配字符串开始 |
\z | 匹配字符串结束 |
\Z | 匹配字符串结束 如果是存在换行,只匹配到换行前的结束字符串。 |
\G | 匹配最后匹配完成的位置 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。 如, er\b 可以匹配 never 中的 er,但不能匹配 verb 中的 er。 |
\B | 匹配非单词边界 如,er\B 能匹配 verb 中的 er,但不能匹配 never 中的 er。 |
\n | 匹配一个换行符 |
\t | **匹配一个制表符 |
实例
匹配 Markdown:
'# (.+)' # 一级标题
'## (.+)' # 二级标题
'### (.+)' # 三级标题
'#{4} (.+)' # 四级标题
'#{5} (.+)' # 五级标题
'#{6} (.+)' # 六级标题
'> (.+)' # 引用
'(`)(.+)\1' # 行内代码
'([*_])(.+)\1' # 斜体
'([*_]{2})(.+)\1' # 粗体
'([*_]{3})(.+)\1' # 斜粗体
'```(.*)\n(.*)\n```'# 代码块,需指定修饰符 re.DOTALL
匹配女朋友
回到标题提出的问题:如何用正则表达式匹配女朋友?
来看看这个例子:
peoples = 'People1People2MyGirlfriendPeople3People4'
开始匹配:
mygirlfriend = re.search('MyGirlfriend', peoples)
查看结果:
>>> mygirlfriends.group()
MyGirlfriend
成功!
赶快去匹配一个女朋友吧!
什么?你没有女朋友?点击查看追女生秘籍:https://blog.csdn.net/weixin_48448842/article/details/119630331
以及炫酷的播放器:
七夕将至,我用Python给女友做了个炫酷的音乐播放器,她直夸我厉害!
原创不易,如果你匹配到了女朋友的话,
点赞收藏再走吧!
关注作者,互助交流,学习更多 Python 知识!
https://blog.csdn.net/weixin_48448842
推荐阅读