【Python爬虫】体验正则表达式的魅力
高效文本处理 - 1
张伟 13497113770 \n 王伟 18848534265 \n 王芳 14055574177 \n 李伟 18778349318 \n 王秀英 17868446857 \n 李秀英 13837762154 \n 李娜 14251562703 \n 张秀英 17734621265 \n 刘伟 13758327790 \n 张敏 14427564623 \n 李静 13566484867 \n 张丽 14344816212 \n 王静 14051265514 \n 王丽 15584308325 \n 李强 17529536074 \n 张静 17758961128 \n 李敏 13266778621 \n 王敏 13568158219 \n 王磊 13725567211 \n 李军 15897558217 \n 刘洋 17672244822 \n
提取所有 11 位数字电话号码
\d{11}
结果:
13497113770 18848534265 14055574177 18778349318 17868446857 13837762154 14251562703 17734621265 13758327790 14427564623 13566484867 14344816212 14051265514 15584308325 17529536074 17758961128 13266778621 13568158219 13725567211 15897558217 17672244822
提取所有 18 或 13 开头的电话号码
(18|13)\d{9}
结果:
13497113770 18848534265 18778349318 13837762154 13758327790 13566484867 13266778621 13568158219 13725567211
提取所有“王”姓同学的名字
王\S*
结果:
王伟
王芳
王秀英
王静
王丽
王敏
王磊
提取所有“张”姓同学的电话号码
(张\S*) *(\d{11}) $1 的电话是 $2
结果:
张伟 的电话是 13497113770 张秀英 的电话是 17734621265 张敏 的电话是 14427564623 张丽 的电话是 14344816212 张静 的电话是 17758961128
重新排版
(\S*) *(\d{11}) $1 - $2
结果:
张伟 - 13497113770 王伟 - 18848534265 王芳 - 14055574177 李伟 - 18778349318 王秀英 - 17868446857 李秀英 - 13837762154 李娜 - 14251562703 张秀英 - 17734621265 刘伟 - 13758327790 张敏 - 14427564623 李静 - 13566484867 张丽 - 14344816212 王静 - 14051265514 王丽 - 15584308325 李强 - 17529536074 张静 - 17758961128 李敏 - 13266778621 王敏 - 13568158219 王磊 - 13725567211 李军 - 15897558217 刘洋 - 17672244822
几乎所有的 IDE、编程语言、稍高级文本编辑器都支持使用正则表达式进行以上提取和替换操作
高效文本处理 - 2
原始文本
张伟 1993-2-5 王伟 1994.7.1 王芳 1997-6-28 李伟 1993-12-26 王秀英 1999-11-16 李秀英 1991年12月27日 李娜 1996.6.25 张秀英 1993.8.26 刘伟 1992-4-28 张敏 1998年5月24日 李静 1996年8月21日 张丽 1999年5月15日 王静 1994.6.2 王丽 1995-6-13 李强 1999.6.19 张静 1998年11月4日 李敏 1990.9.19 王敏 1999.12.8 王磊 1999.5.22 李军 1992-4-25 刘洋 1994.3.16
提取所有日期
\d{4}\S\d{1,2}\S\d{1,2}\S?
结果:
1993-2-5 1994.7.1 1997-6-28 1993-12-26 1999-11-16 1991年12月27日 1996.6.25 1993.8.26 1992-4-28 1998年5月24日 1996年8月21日 1999年5月15日 1994.6.2 1995-6-13 1999.6.19 1998年11月4日 1990.9.19 1999.12.8 1999.5.22 1992-4-25 1994.3.16
提取所有 1996 年以前出生的学生
(\S*) *199[0-5]\S\d{1,2}\S\d{1,2}\S?
结果:
张伟 1993-2-5 王伟 1994.7.1 李伟 1993-12-26 李秀英 1991年12月27日 张秀英 1993.8.26 刘伟 1992-4-28 王静 1994.6.2 王丽 1995-6-13 李敏 1990.9.19 李军 1992-4-25 刘洋 1994.3.16
重新排版
(\S*) *(\d{4})\S(\d{1,2})\S(\d{1,2})\S? $1: $2 年 $3 月 $4 日
结果:
张伟: 1993 年 2 月 5 日 王伟: 1994 年 7 月 1 日 王芳: 1997 年 6 月 28 日 李伟: 1993 年 12 月 26 日 王秀英: 1999 年 11 月 16 日 李秀英: 1991 年 12 月 27 日 李娜: 1996 年 6 月 25 日 张秀英: 1993 年 8 月 26 日 刘伟: 1992 年 4 月 28 日 张敏: 1998 年 5 月 24 日 李静: 1996 年 8 月 21 日 张丽: 1999 年 5 月 15 日 王静: 1994 年 6 月 2 日 王丽: 1995 年 6 月 13 日 李强: 1999 年 6 月 19 日 张静: 1998 年 11 月 4 日 李敏: 1990 年 9 月 19 日 王敏: 1999 年 12 月 8 日 王磊: 1999 年 5 月 22 日 李军: 1992 年 4 月 25 日 刘洋: 1994 年 3 月 16 日
把所有 1996 年以前出生的学生出生年份改为 1996
(\S*) *(199[0-5])\S(\d{1,2})\S(\d{1,2})\S? $1: 1996 年 $3 月 $4 日
结果:
张伟: 1996 年 2 月 5 日 王伟: 1996 年 7 月 1 日 李伟: 1996 年 12 月 26 日 李秀英: 1996 年 12 月 27 日 张秀英: 1996 年 8 月 26 日 刘伟: 1996 年 4 月 28 日 王静: 1996 年 6 月 2 日 王丽: 1996 年 6 月 13 日 李敏: 1996 年 9 月 19 日 李军: 1996 年 4 月 25 日 刘洋: 1996 年 3 月 16 日
提取生日
(\S*) *(\d{4})\S(\d{1,2})\S(\d{1,2})\S? $1的生日是$3月$4号🎂
结果:
张伟的生日是2月5号🎂
王伟的生日是7月1号🎂
王芳的生日是6月28号🎂
李伟的生日是12月26号🎂
王秀英的生日是11月16号🎂
李秀英的生日是12月27号🎂
李娜的生日是6月25号🎂
张秀英的生日是8月26号🎂
刘伟的生日是4月28号🎂
张敏的生日是5月24号🎂
李静的生日是8月21号🎂
张丽的生日是5月15号🎂
王静的生日是6月2号🎂
王丽的生日是6月13号🎂
李强的生日是6月19号🎂
张静的生日是11月4号🎂
李敏的生日是9月19号🎂
王敏的生日是12月8号🎂
王磊的生日是5月22号🎂
李军的生日是4月25号🎂
刘洋的生日是3月16号🎂
正则表达式的可读性 非常差,但写起来并没有那么困难,上面每个正则表达式,仅花了十几秒就写完了
代码重构
def fib(): return ((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)) def subfib(start, end): for cur in fib(): if cur > end: return if cur >= start: print cur yield cur def foo(a, b): return a + b
调整缩进,将四空格缩进重构为八个空格
^(\s+) $1$1
结果:
def fib(): return ((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)) def subfib(start, end): for cur in fib(): if cur > end: return if cur >= start: print cur yield cur def foo(a, b): return a + b print 'fibonacci 10~100:' print subfib(10, 100)
重构 Python2 的 print 语法为 Python3 的 print() 函数
print *(.*)$ print($1)
结果:
def subfib(start, end): for cur in fib(): if cur > end: return if cur >= start: print(cur) yield cur def foo(a, b): return a + b print('fibonacci 10~100:') print(subfib(10, 100))
所有函数声明添加 func_ 前缀
def *(.*) def func_$1
结果:
def func_subfib(start, end): for cur in fib(): if cur > end: return if cur >= start: print cur yield cur def func_foo(a, b): return a + b print 'fibonacci 10~100:' print subfib(10, 100)
交换函数声明中的参数位置
def (.*?)\((\w+), *(\w+)\) def $1($3, $2)
结果:
def subfib(end, start): for cur in fib(): if cur > end: return if cur >= start: print cur yield cur def foo(b, a): return a + b print 'fibonacci 10~100:' print subfib(10, 100)
为所有函数添加注释模板
def *(.*): def $1: """ 函数描述: 参数: 返回值: """
结果:
def fib(): """ 函数描述: 参数: 返回值: """ return ((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)) def subfib(start, end): """ 函数描述: 参数: 返回值: """ for cur in fib(): if cur > end: return if cur >= start: print cur yield cur def foo(a, b): """ 函数描述: 参数: 返回值: """ return a + b print 'fibonacci 10~100:' print subfib(10, 100)
正则表达式在代码分析方面有广泛应用,编辑器代码高亮都是用正则表达式实现的。
不过正则表达式并非万能,比如第三步中为函数添加前缀时,并未对函数调用的地方添加前缀,还需要后续处理。
数据格式验证
数据格式验证是正则表达式的一个常用领域,网站通常使用正则表达式来判断用户提交的信息是否符合规范。
下面的正则表达式都相当复杂,幸运的是你不需要记忆这些常用的正则表达式,需要时通过任何搜索引擎都能够找到。
邮箱验证
^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$
输入数据
123@qq.com asdf@gmail.com surname@blah.com name.name@123.com 1242135.com @foo.com a@a name @bla.com
123@qq.com
asdf@gmail.com
surname@blah.com
name.name@123.com
密码强度验证
(最少八个字符,至少一个大写字母,一个小写字母和一个数字)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^\n]{8,}$
输入数据
123456 wdfqe#wefDdf123 wjleif932 8Ij12340 password 11111111ABc hello qweasdzxc
合法数据
wdfqe#wefDdf123 8Ij12340 11111111ABc
18 位身份证号验证
^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$
输入数据
23010519491231002X 33010517491231232X 67810519491331214X 22010519491232452X 123412195292349132 123412196712234932 a23rr23451235t123f 124123580913457102
合法数据
23010519491231002X
123412196712234932
IP 地址验证
^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
输入数据
1.0.0.0 12.3.4.5 192.168.1.1 192.168.256.1 1.2.2.2 0.0.0.0 2.3.4 -1.2.3.4
合法数据
1.0.0.0 12.3.4.5 192.168.1.1 1.2.2.2 0.0.0.0
手机号验证
^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$
输入数据
12345678900
12354125235
15423423523
15123458654
8613890235892
017728384893
11111111111
合法数据
15123458654
8613890235892
017728384893
有一些网站提供了常用的正则表达式和测试环境,例如
- regexr.com 一个非常棒的在线环境,我经常使用
- regexlib.com 收录了很多严谨的正则表达式,不过也相当复杂
网络爬虫
网络爬虫提取数据也离不开正则表达式。
原始文本
<div class="hotnews"> <div class="imgview" id="imgView"><a href="https://xinwen.eastday.com/a/n181211075002407.html?qid=news.baidu.com" target="_blank"><img src="https://imgsa.baidu.com/news/q%3D100/sign=cdae0fb78a94a4c20c23e32b3ef51bac/cefc1e178a82b90151b62d8b7e8da9773912ef6b.jpg"></a></div><ul><li class="hdline0"> <a href="http://www.xinhuanet.com/politics/xxjxs/2018-12/11/c_1123834898.htm" target="_blank" class="a3"> XXX的改革之“喻” </a></li> <li class="hdline1"> <a href="http://news.cri.cn/20181211/313376c7-77cc-abff-3a81-bd855c0a8577.html" target="_blank"> 《必由之路》宣传片</a> <i style="font-size: 12px"> </i><a href="http://politics.gmw.cn/2018-12/11/content_32146726.htm" target="_blank"> 主题歌《梦想阳光》发布 </a> </li> <li class="hdline2"> <img src="https://imgsa.baidu.com/news/q%3D100/sign=ab45ee53bbfd5266a12b38149b199799/f9198618367adab46063f9fb86d4b31c8601e4d3.jpg"><a href="http://politics.people.com.cn/n1/2018/1211/c1001-30458946.html" target="_blank" class="a3"> 【央视快评】坚持中国特色人权发展道路</a></li> <li class="hdline3"> <a href="http://news.cri.cn/20181210/384ab948-e36b-b455-9d97-8eb05172c179.html" target="_blank">同舟共济</a> <i style="font-size: 12px"> </i><a href="http://news.cctv.com/2018/12/10/ARTI9v2GwcDNkh8obJh2vnUy181210.shtml" target="_blank"> 《改革开放 关键一招》第一集</a> </li> <li class="hdline4"> <a href="http://news.cctv.com/2018/12/10/ARTISzd4ekNLNB88EFFtMgB7181210.shtml" target="_blank" class="a3"> 【数说改革开放40年】40年减贫7.4亿人</a></li> <li class="hdline5"> <a href="http://news.ifeng.com/a/20181211/60188943_0.shtml?_zbs_baidu_news" target="_blank">王岐山出席的这个活动,有什么来头?</a> </li> </ul> </div>
提取所有 HTML 标签
<("[^"]*"|'[^']*'|[^'">])*>
结果:
<div class="hotnews"> <div class="imgview" id="imgView"> <a href="https://xinwen.eastday.com/a/n181211075002407.html?qid=news.baidu.com" target="_blank"> <img src="https://imgsa.baidu.com/news/q%3D100/sign=cdae0fb78a94a4c20c23e32b3ef51bac/cefc1e178a82b90151b62d8b7e8da9773912ef6b.jpg"> </a> </div> <ul> <li class="hdline0"> <a href="http://www.xinhuanet.com/politics/xxjxs/2018-12/11/c_1123834898.htm" target="_blank" class="a3"> </a> </li> <li class="hdline1"> <a href="http://news.cri.cn/20181211/313376c7-77cc-abff-3a81-bd855c0a8577.html" target="_blank"> </a> <i style="font-size: 12px"> </i> <a href="http://politics.gmw.cn/2018-12/11/content_32146726.htm" target="_blank"> </a> </li> <li class="hdline2"> <img src="https://imgsa.baidu.com/news/q%3D100/sign=ab45ee53bbfd5266a12b38149b199799/f9198618367adab46063f9fb86d4b31c8601e4d3.jpg"> <a href="http://politics.people.com.cn/n1/2018/1211/c1001-30458946.html" target="_blank" class="a3"> </a> </li> <li class="hdline3"> <a href="http://news.cri.cn/20181210/384ab948-e36b-b455-9d97-8eb05172c179.html" target="_blank"> </a> <i style="font-size: 12px"> </i> <a href="http://news.cctv.com/2018/12/10/ARTI9v2GwcDNkh8obJh2vnUy181210.shtml" target="_blank"> </a> </li> <li class="hdline4"> <a href="http://news.cctv.com/2018/12/10/ARTISzd4ekNLNB88EFFtMgB7181210.shtml" target="_blank" class="a3"> </a> </li> <li class="hdline5"> <a href="http://news.ifeng.com/a/20181211/60188943_0.shtml?_zbs_baidu_news" target="_blank"> </a> </li> </ul> </div>
清洗所有 HTML 标签
<("[^"]*"|'[^']*'|[^'">])*>
结果:
同舟共济 《改革开放 关键一招》第一集 【数说改革开放40年】40年减贫7.4亿人 王岐山出席的这个活动,有什么来头?
提取所有 URL
(https?|ftp|file)(:/)?/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]
结果:
https://xinwen.eastday.com/a/n181211075002407.html?qid=news.baidu.com https://imgsa.baidu.com/news/q%3D100/sign=cdae0fb78a94a4c20c23e32b3ef51bac/cefc1e178a82b90151b62d8b7e8da9773912ef6b.jpg http://www.xinhuanet.com/politics/xxjxs/2018-12/11/c_1123834898.htm http://news.cri.cn/20181211/313376c7-77cc-abff-3a81-bd855c0a8577.html http://politics.gmw.cn/2018-12/11/content_32146726.htm https://imgsa.baidu.com/news/q%3D100/sign=ab45ee53bbfd5266a12b38149b199799/f9198618367adab46063f9fb86d4b31c8601e4d3.jpg http://politics.people.com.cn/n1/2018/1211/c1001-30458946.html http://news.cri.cn/20181210/384ab948-e36b-b455-9d97-8eb05172c179.html http://news.cctv.com/2018/12/10/ARTI9v2GwcDNkh8obJh2vnUy181210.shtml http://news.cctv.com/2018/12/10/ARTISzd4ekNLNB88EFFtMgB7181210.shtml http://news.ifeng.com/a/20181211/60188943_0.shtml?_zbs_baidu_news
提取所有 JPG 图片的 URL
(https?|ftp|file)(:/)?/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|].jpg
结果:
https://imgsa.baidu.com/news/q%3D100/sign=cdae0fb78a94a4c20c23e32b3ef51bac/cefc1e178a82b90151b62d8b7e8da9773912ef6b.jpg
https://imgsa.baidu.com/news/q%3D100/sign=ab45ee53bbfd5266a12b38149b199799/f9198618367adab46063f9fb86d4b31c8601e4d3.jpg
提取所有中文和中文标点
[\u4e00-\u9fa5\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b]+
结果:
XXX的改革之“喻”
《必由之路》宣传片
主题歌《梦想阳光》发布
央视快评
坚持中国特色人权发展道路
同舟共济
《改革开放
关键一招》第一集
数说改革开放
年
年减贫
亿人
王岐山出席的这个活动,有什么来头?
本文来自博客园,作者:木子欢儿,转载请注明原文链接:https://www.cnblogs.com/HGNET/p/13299789.html