正则表达式的使用
正则表达式的匹配规则网上都有,这里不放出来了,毕竟只是记录学习的博文。 以下讲几个一直没搞明白的点。
贪婪与非贪婪
实现介绍通用匹配,以.*
表示。.
代表匹配任意字符,*
代表匹配0个或多个表达式所以两个连用就代表匹配任意字符。比如字符串'Hello Python and Anaconda'
,表达式为'^Hello.*Anaconda$'
。代码如下: 1
2
3
4
5import re
txt = 'Hello Python and Anaconda'
result = re.match("^Hello.*Anaconda$", txt)
print(result.group()).*
代表匹配任意个字符,所以该正则表达式会在Hello之后一直匹配成功,直到遇到Anaconda停止。其中.*
其实就是贪婪匹配。但是有时候贪婪匹配会出很大的问题。比如字符串'My tel number is 15012345678'
,正则表达式为'^My.*(\d+)$'
。具体代码如下: 1
2
3
4
5
6import re
txt = 'My tel number is 15012345678'
result = re.match("^My.*(\d+)$", txt)
print(result.group())
print(result.group(1))(\d+)
代表一个组,这个组里面匹配的东西就是我们需要的结果,而我们的代码也看起来很正常\d+
就意味着匹配多个数字。可以看到这段代码print(result.group(1))
就是输出手机号。但是结果却只匹配到了8,因为.*
代表了贪婪匹配,它会尽可能的匹配到多的字符。因为.*
代表匹配任意多的字符串,所以它看到1501234567会一直往下匹配,知道看到8,发现8已经是最后一个数字了,如果这个8不与\d+
匹配岂不是出现系统漏洞了,因为\d+
就是让你匹配数字,你不匹配不是违反了规则?所以匹配成功。最后将8加入组中,通过result.group(1)获取到这一组。所以贪婪匹配在这种情况是有问题,这就引出了非贪婪匹配:.*?
。代码如下: 1
2
3
4
5
6import re
txt = 'My tel number is 15012345678'
result = re.match("^My.*?(\d+)$", txt)
print(result.group())
print(result.group(1)).*?
,而不是贪婪模式.*
。
修饰符
代码 1
2
3
4
5
6import re
txt = 'My tel number is 15012345678'
result = re.match("^My.*?(\d+)$", txt, re.S)
print(result.group())
print(result.group(1))
re模块中的方法
- match() 这方法从头开始匹配,如果一开始即第一个字符就不匹配,直接就算匹配失败。可以用于校验用户输入的信息是否合乎规范。
- search() 从头开始匹配,扫描整个字符串,如果碰到一段字符串匹配成功了就立即返回,它只会返回一个结果。
- findall() 跟它名字一样,扫描整个字符串,获得所有匹配成功的结果。
- 待补充。。。
举一个栗子
爬取牛客网的技术栈。