正则表达式之match()
正则表达式是处理字符串的强大工具,有自己特定的语法结构,可以实现字符串的检索、替换、匹配验证。
开源中国提供的正则表达式测试工具,输入待匹配的文本,然后选择常用的正则表达式就可以得出相应的匹配结果了。
对于URL来说,可以用下面的正则表达式匹配:[a-zS-z]+://[^\s]*。
用这个正则表达式去匹配一个字符串,如果中国字符串包含类似URL的文本,就会被提取出来。
这个正则表达式看上去是乱糟糟的一团,其实不然。如a-z代表匹配任意小写字母,\s表示匹配任意的空白字符,*就代表匹配前面的字符可以任意多个。
python的re库提供了整个正则表达式的实现。
1.match()
match()方法会尝试从字符串的起始位置匹配正则表达式,如果匹配,就返回匹配成功的结构;如果不匹配,就返回None。示例如下:
import re
content='Hello 1234567 World_This is a Regex Demo'
result=re.match('^Hello\s(\d+)\sWorld',content)
print(result)
print(result.group())
print(result.group(1))
print(result.span())
运行结果如下:
<re.Match object; span=(0, 19), match='Hello 1234567 World'>
Hello 1234567 World
1234567
(0, 19)
group()会输出完整的匹配结果,而group1()会输出第一个被()包围的匹配结果。
1.通用匹配
.*(点星)是一个万能匹配。其中.(点)可以匹配任意字符(除换行符),*代表匹配前面的字符无限次。
import re
content='Hello 1234567 World_This is a Regex Demo'
result=re.match('^Hello.*Demo$',content)
print(result)
print(result.group())
print(result.span())
这里我们将中间部分直接省略,全用.*来代替,最后加一个结尾字符串。运行结果如下:
<re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
Hello 1234567 World_This is a Regex Demo
(0, 40)
2.贪婪与非贪婪
import re
content='Hello 1234567 World_This is a Regex Demo'
result=re.match('^He.*(\d+).*Demo$',content)
print(result)
print(result.group(1))
这里我们依然想获取中间的数字,所以中间依然写的是(\d+)。而数字两侧由于内容比较杂乱,所以想省略来写。运行结果如下:
<re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
7
可以发现我们只得到了7这个数字。这里涉及一个贪婪匹配与非贪婪匹配的问题。在贪婪匹配下, .*会匹配尽可能多的字符。正则表达式中.*后面是\d+,也就是至少一个数字,并没有指定具体多少给数字,因此,.*就尽可能匹配多的字符,这里就把123456匹配了,给\d+留下一个可满足条件的数字7。
这时,我们可以使用非贪婪匹配来解决这个问题。它的写法是.*?。
非贪婪匹配就是尽可能匹配少的字符。当.*?匹配到Hello后面的空白字符时,再往后的字符就是数字了,而\d+恰好可以匹配,.*?就不再进行匹配,交给\d+去匹配后面的数字。
但需要注意,如果匹配的结果在字符串尾,.*?就可能匹配不到任何内容了。
import re
content='http://weibo.com/comment/kEraCN'
result1=re.match('http.*?comment/(,*?)',content)
result2=re.match('http.*?comment/(.*)',content)
print('result1',result1.group(1))
print('result2',result2.group(1))
运行结果如下:
result1
result2 kEraCN
可以观察到,.*?没有匹配到任何结果,而.*则尽量匹配多的内容,成功得到了匹配结果。
3.修饰符
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。
import re
content='''Hello 1234567 World_This
is a Regex Demo
'''
result=re.match('^He.*?(\d+).*?Demo$',content)
print(result.group(1))
与上例相仿,我们在字符串中加了换行符,但运行直接报错,我们又调用了group()方法导致AttributeError。
.匹配的是除换行符之外的任意字符每当遇到换行符,.*?就不能匹配了,所以导致匹配失败,这里只需加一个修饰符re.S,即可修正这个错误:result=re.match('^He.*?(\d+).*?Demo$',content,re.S)
4.转义匹配
如果目标字符串里就包含,,就需要用到转义匹配:
import re
content='(百度)www.baidu.com'
result=re.match('\(百度\)www\.baidu\.com',content)
print(result)
当遇到用于正则匹配模式的特殊字符时,在前面加反斜线转义一下即可。例如.就可以用\.来匹配,运行结果如下:
已连接到 pydev 调试器(内部版本号 231.9011.38)<re.Match object; span=(0, 17), match='(百度)www.baidu.com'>
可以看到,这里成功匹配到了原字符串。
CSDN-Ada助手: 恭喜你这篇博客进入【CSDN月度精选】榜单,全部的排名请看 https://bbs.csdn.net/topics/617346504。
CSDN-Ada助手: 恭喜您撰写了第18篇博客!标题“抓取猫眼电影排行上”非常吸引人。您对猫眼电影排行的抓取确实让读者可以更好地了解电影市场动态。希望您能继续坚持创作,为大家带来更多有趣且有价值的内容。 如果我可以提供一些建议的话,我希望在未来的博客中您能够更深入地探讨一些电影排行背后的原因和趋势,或者分享一些独到的观点和见解。这样的话,读者们将更容易从您的博客中获得启发和思考。不过,无论如何,我相信您一定会在创作的道路上不断进步的。期待您下一篇博客的问世!
CSDN-Ada助手: 恭喜您写了第19篇博客!标题“抓取猫眼电影排行下”听起来非常吸引人。您一直坚持创作,真是令人敬佩。我希望您能继续保持这样的创作热情,为我们带来更多精彩的内容。 在下一步的创作中,或许您可以考虑加入一些有关猫眼电影排行榜的分析,或者分享一些您对电影评价的见解。这样的创作建议只是我个人的观点,希望能对您有所帮助。期待看到您未来更多精彩的博客!
CSDN-Ada助手: 恭喜你这篇博客进入【CSDN每天值得看】榜单,全部的排名请看 https://bbs.csdn.net/topics/617180669。
CSDN-Ada助手: 恭喜您写了第20篇博客!标题“使用XPath上”听起来很有趣。您在持续创作方面做得非常出色,能够坚持写下去是一个了不起的成就。在下一步的创作中,或许您可以考虑分享一些XPath的实际应用案例,或者深入探讨XPath在不同领域的应用。希望您能继续保持谦虚的态度,因为您的知识和经验对读者来说是宝贵的财富。期待看到更多精彩的内容!