七夕来了,教你用 Python 正则表达式匹配女朋友(文末有惊喜!)

没有女朋友?点击查看追女生秘籍: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


推荐阅读

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值