re 闲话
认识 re 还是我很早开始写爬虫的时候,那时候觉得匹配规则很难写,之前还遇到了一些坑,当然现在回头看觉得自己太蠢了。re 在不同编程语言中都有应用,最重要的匹配遇到的坑,有些方法只匹配开头,或者只匹配单行,而不是全部匹配,这也是我当时写了很久匹配不到的原因,反正大致是这个问题吧。主要是对 re 表达式 和 编程语言中的 re 模块使用都不是很了解,所以碰壁。
re 我愿称之为文本处理界的瑞士军刀,如果 re 解决不了的问题,大概没人能解决吧。但是术业有专攻,处理 json xml html 等都有对应的工具,没必要写个复杂的 re 去处理。
re 核心
“断言”
没错,我单独为它写一行,因为自从遇到了断言后我就没有不会写的匹配表达式了。
“正向先行断言,负向先行断言,正向后行断言,负向后行断言”
事实上,如果不是经常性写,很容易忘了这四个,但是没关系,用的时候搜断言,看看别人的举例就马上可以有概念了,留个印象即可。
下面贴上代码:
def regular_assertion():
m_str = r'regex represents regular expression'
print(f'match str:{m_str}')
for index, value in enumerate(m_str):
print(index, end='')
print(value, end=' ')
# 正向先行断言 负向先行断言 正向后行断言 负向后行断言
reg = [r're(?=gular)', r're(?!g)', r'(?<=\w)re', r'(?<!\w)re']
for i in range(4):
print(f'\n匹配规则:{reg[i]}')
m = re.finditer(reg[i], m_str)
if m:
print(f'匹配结果:')
for _ in m:
print(_, end=' ')
print(_.group(), end='; ')
if __name__ == '__main__':
regular_assertion()
"""打印结果
match str:regex represents regular expression
0r 1e 2g 3e 4x 5 6r 7e 8p 9r 10e 11s 12e 13n 14t 15s 16 17r 18e 19g 20u 21l 22a 23r 24 25e 26x 27p 28r 29e 30s 31s 32i 33o 34n
匹配规则:re(?=gular)
匹配结果:
<re.Match object; span=(17, 19), match='re'> re;
匹配规则:re(?!g)
匹配结果:
<re.Match object; span=(6, 8), match='re'> re; <re.Match object; span=(9, 11), match='re'> re; <re.Match object; span=(28, 30), match='re'> re;
匹配规则:(?<=\w)re
匹配结果:
<re.Match object; span=(9, 11), match='re'> re; <re.Match object; span=(28, 30), match='re'> re;
匹配规则:(?<!\w)re
匹配结果:
<re.Match object; span=(0, 2), match='re'> re; <re.Match object; span=(6, 8), match='re'> re; <re.Match object; span=(17, 19), match='re'> re;
"""
解析:
[r’re(?=gular)‘, r’re(?!g)’, r’(?<=\w)re’, r’(?<!\w)re’]
举例:r’re(?=gular)’
r’ 这个是python表示raw字符串的含义,防止转义,写过代码的应该都知道 \t,\n 这类的
re 这个是表示匹配的对象是 re 字符串,也可以换成 \d+,\w,这类的正则表达式,你需要知道你的表达式的含义
(?=gular) 这个就是断言了
三者连起来就是 非转义的原生字符串(即完整的正则表达式):re(?=gular),匹配 re 这两个字母,且 re 后面跟的一定是 gular,即断言 re 后 跟 gular,匹配的结果是 re,并不包含断言内容
其他几个同理(其他几个稍微复杂一点点,一丢丢,嘿嘿,嘿嘿)
正则注意事项
大小写区分,在写代码的时候可以看看对应编程语言的参考手册,如何忽略大小写匹配,有些时候我们不在乎大小写的区别。
记住 “断言” 就好了,什么时候忘了,搜索 断言 + 正则 温习一下。