更新说明
后续更新笔记元信息,重读一遍发现写的不太好,非常难理解
推倒重写一篇,精简文章,仅提炼出过程、知识点
问题产生过程
讲讲开发项目过程遇到的问题
需求是检测数组中每个属性的值是否数组,也就是通过判断是否开头是空格+换行符( \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个条件,则判断该属性的值是数组类型
- 不管前面有多少个空格:
\s+
- 结尾是换行符:
[\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 """
|
原因在于使用的正则方法上
search
和match
方法,一个全字段匹配,一个开头匹配
我这里采用了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'))
|
可以发现匹配不到,因为com
,并不在'www.runoob.com'
的开头,所以匹配不到
而search
不一样,search
搜索的是全字段
就是说不管在哪个位置,都能找到
1 2 3
| import re txt = 'www.runoob.com' print(re.search('com', 'www.runoob.com'))
|
当然,加上元字符^
,其实也等同于match
1 2 3 4 5
| import re txt = 'www.runoob.com' print(re.search('^com', 'www.runoob.com')) print(re.search('^run', 'www.runoob.com')) print(re.search('^www', 'www.runoob.com'))
|
总结
如果打算完全匹配某个字符串或者匹配开头的话,使用以下两种方法
search
+^
元字符
match
方法
如果打算匹配一小段文本,不管位置的话,采用search
方法