Python正则的绝对匹配和部分匹配

更新说明

后续更新笔记元信息,重读一遍发现写的不太好,非常难理解

推倒重写一篇,精简文章,仅提炼出过程、知识点

问题产生过程

讲讲开发项目过程遇到的问题
需求是检测数组中每个属性的值是否数组,也就是通过判断是否开头是空格+换行符( \n)进行判断

匹配文本如下(json格式):

1
2
3
4
5
6
7
[
" 回路殷勤 \n",
" \n",
" 2022-11-04 22:14 \n",
" 2022-11-04 22:34\n",
"\n"
]

写个正则判断,符合2个条件,则判断该属性的值是数组类型

  1. 不管前面有多少个空格:\s+
  2. 结尾是换行符:[\n]
1
r_key = re.compile(r'\s+[\n]')

然后问题产生,我使用正则的方法search去匹配,结果如下
原期望的结果是只匹配第3行(" \n"),但是发生了预期外的错误,返回了3个结果

1
2
3
4
5
[
" 回路殷勤 \n",
" \n",
" 2022-11-04 22:14 \n"
]

解决方法

为什么会匹配3个值,而不是1个值(第4行)?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import re
a = [
" 回路殷勤 \n",
" \n",
" 2022-11-04 22:14 \n",
" 2022-11-04 22:34\n",
"\n"
]

r_key = re.compile(r'\s+[\n]')
for i in a:
try:
print(re.search(r_key,i))
except:
continue
"""
<re.Match object; span=(5, 7), match=' \n'>
<re.Match object; span=(0, 2), match=' \n'>
<re.Match object; span=(17, 19), match=' \n'>
None
None
"""

原因在于使用的正则方法上
searchmatch方法,一个全字段匹配,一个开头匹配

我这里采用了search方法,相当于全字段匹配,也就是说不管空格+换行符( \n)在全字段哪个位置,都会匹配上,所以导致了预期外的错误

修改下使用的方法即可,修改后符合预期:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import re
a = [
" 回路殷勤 \n",
" \n",
" 2022-11-04 22:14 \n",
" 2022-11-04 22:34\n",
"\n"
]

r_key = re.compile(r'\s+[\n]')
for i in a:
try:
print(re.match(r_key,i))
except:
continue
"""
None
<re.Match object; span=(0, 2), match=' \n'>
None
None
None
"""

两者的区别

match采用的是开头匹配,如果被匹配字段从一开始就不在开头,那就匹配不到

示例:

1
2
3
import re
txt = 'www.runoob.com'
print(re.match('com', 'www.runoob.com')) # None

可以发现匹配不到,因为com,并不在'www.runoob.com'的开头,所以匹配不到

search不一样,search搜索的是全字段
就是说不管在哪个位置,都能找到

1
2
3
import re
txt = 'www.runoob.com'
print(re.search('com', 'www.runoob.com')) # <re.Match object; span=(11, 14), match='com'>

当然,加上元字符^,其实也等同于match

1
2
3
4
5
import re
txt = 'www.runoob.com'
print(re.search('^com', 'www.runoob.com')) # None
print(re.search('^run', 'www.runoob.com')) # None
print(re.search('^www', 'www.runoob.com')) # <re.Match object; span=(0, 3), match='www'>

总结

如果打算完全匹配某个字符串或者匹配开头的话,使用以下两种方法

  1. search+^元字符
  2. match方法

如果打算匹配一小段文本,不管位置的话,采用search方法


Python正则的绝对匹配和部分匹配
https://linguoguang.com/2023/01/23/Python正则的绝对匹配和部分匹配/
作者
linguoguang
发布于
2023年1月23日
许可协议