趣文网,分享全网好句子、好文章!

爬虫要讲武德 你却用正则 一篇文章搞定正则表达式

时间:2023-09-13 04:13:01

相关推荐

爬虫要讲武德 你却用正则 一篇文章搞定正则表达式

来源:麦叔编程

作者: 麦叔

正则表达式是爬虫,Web开发,数据处理等各类涉及到文本处理的一把锋利的瑞士军刀,是每个程序员必须掌握的一门技能。本文稍微有点长,但耐心看完,实践其中的例子,你的功力必会更精进一层!

1. 正则表达式的7个境界

假设有一段文字:

text = "身高:178,体重:168,学号:123456,密码:9527"

要确定文本中是否包含数字123456,我们可以用in运算符,也可以使用index函数:

text = "身高:178,体重:168,学号:123456,密码:9527"target = "123456"if target in text:print("找到了")print(text.index(target))

但当问题变得复杂的时候,比如找出字符串中所有数字,用基本的字符串处理就不行了。

这不再是一个固定的字符串匹配问题,而是一个模式,一种规则的匹配。为了解决这个问题,有位叫Stephen的大神在1951年提出了正则表达式。

几乎任何一门通用编程语言都有专门的正则表达式的模块,正则表达式英文是regular expressesion,所以编程语言中的模块名字一般叫re,或者regex等。Python中的正则表达式处理模块是re。

正则表达式就是为了找到符合某种模式的字符串,这些模式包括:是什么字符,重复多少次,在什么位置,有哪些额外的约束。请注意:这里的每一句话都对应了正则表达式中的一类语法。

下面我们通过8个例子,来熟悉正则表达式,后面再讲写正则表达式的套路和正则表达式的语法。

level1 - 固定的字符串

要求:确定字符串中是否有123456

import retext = "麦叔身高:178,体重:168,学号:123456,密码:9527"print(re.findall(r"123456", text))

代码说明:

第1行,引入正则表达式模块re

第3行,使用re的findall()方法找到所有符合模式的字符串,这里的模式就是123456,也就是说找到字符串中所有的123456。findall()方法的第1个参数是模式,第2个参数是要查找的字符串。模式中会有一些特殊字符,所以用r表示这是一个raw字符串,让Python不要去转义里面的特殊字符。上面程序的运行结果是:[123456],因为整个字符串中就1个123456。

level1就是一个固定的字符串匹配,可以用传统的字符串匹配解决。

level2 - 某一类字符

要求:找出所有的单个的数字

text = "麦叔身高:178,体重:168,学号:123456,密码:9527"print(re.findall(r"d", text))

这个表达式

d

表示所有的数字,所以1,7,8,1,6,8等都可以匹配到。这是很简单的模式,只匹配1个单独的数字。

如果你完全没有接触过正则表达式,看着有点懵逼,去我看在B站的视频吧,让我手把手教你!

level3 - 重复某一类字符

要求:找所有的数字,比如178,168,123456,9527等。

text = "麦叔身高:178,体重:168,学号:123456,密码:9527"print(re.findall(r"d+", text))

这个模式

d+

在d的后面增加了+号,表示数字可以出现1到多次,所以178等都符合它的要求。

leve4 - 组合level2

要求:找出座机号码

text = "麦叔电话是18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166"print(re.findall(r"d{4}-d{8}", text))

d{4}-d{8}

这是一个组合的模式,表示前面4个数字,中间一个横杠,后面8个数字。

这里会匹配一个结果:0571-52152166

leve5 - 多种情况

要求:找出手机号码或者座机号码

text = "麦叔电话是18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166"print(re.findall(r"d{4}-d{8}|1d{10}", text))

比上面有复杂了点,因为使用竖线(|)来表示”或“的关系,就是手机号码和电话号码都可以。

这里会匹配三个结果:18812345678,18887654321,0571-52152166。

level6 - 限定位置

要求:在句子开头的手机号码,或座机

text = "18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166"print(re.findall(r"^1d{10}|^d{4}-d{8}", text))

在表达式的最开始使用了^符号,表示一定要在句子的开头才行。这时候只有18812345678能匹配上。

level7 - 内部约束

要求:找出形如barbar, dardar的前后三个字母重复的字符串

text = "barbar carcar harhel"print(re.findall(r"(w{3})(1)", text))

这里barbar和carcar会匹配上,但harhel不会被匹配,因为它不是3个字符重复的。

w{3}表示3个字符,放在小括号中(w{3})就成为一个分组,而后面的(1)表示它里面的内容和第1个括号里的内容必须相同,其中的1就表示第1个括号,也就是说3个字符要重复出现两次。

2. 写正则表达式的步骤

如何写正则表达式呢?我总结了几个步骤。不管多复杂,基本上都百试不爽。

我们仍然以包含分机号码的座机电话号码为例,比如0571-88776655-9527,演示下面的步骤:

确定模式包含几个子模式

它包含3个子模式:0571-88776655-9527。这3个子模式用固定字符连接。各个部分的字符分类是什么这3个子模式都是数字类型,可以用d。现在可以写出模式为:d-d-d各个子模式如何重复第1个子模式重复3到4次,因为有010和021等直辖市第2个子模式重复7到8次,有的地区只有7位电话号码第3个子模式重复3-4次加上次数限制后,模式成为:d{3,4}-d{7,8}-d{3,4}但有的座机没有分机号,所以我们用或运算符让它支持两者:d{3,4}-d{7,8}-d{3,4}|d{3,4}-d{7,8}是否有外部位置限制没有是否有内部制约关系没有经过一通分析,最后的正则就写成了,测试一下:

text = "随机数字:01234567891,座机1:0571-52152166,座机2:0571-52152188-1234"print(re.findall(r"d{3,4}-d{7,8}-d{3,4}|d{3,4}-d{7,8}", text))

最后的结果是:两个座机都可以找出来。

3. 语法规则

正则表达式几十个符号,看似很复杂,但如果能否分清楚类别和作用,就没那么复杂了。

字符类别表达- 表达某一类字符,比如数字,字母,3到9之间的任何数字等

字符的重复次数,也叫做量词。比如身份证是数字重复15或18次,也就是:d{15}或者d{18}。

组合模式:把多个简单的模式组合在一起,可以是拼接,也可以是二者选其一。

位置:限定模式出现的位置,比如行首,行尾,或者在特定字符之后等。

分组,把一个正则表达式分成几个部分,这样可以重复某个分组,或者指定两个分组必须相同等额外的要求。

其他:

4. Python正则模块re的用法

python的re模块还比较简单,包括以下几个方法:

re.search():查找符合模式的字符,只返回第一个,返回Match对象re.match():和search一样,但要求必须从字符串开头匹配re.findall():返回所有匹配的字符串列表re.finditer():返回一个迭代器,其中包含所有的匹配,也就是Match对象re.sub():替换匹配的字符串,返回替换完成的文本re.subn():替换匹配的字符串,返回替换完成的文本和替换的次数re.split():用匹配表达式的字符串做分隔符分割原字符串re.compile():把正则表达式编译成一个对象,方便后面使用5. 更多例子

下面我举了更多的例子,供大家练习和熟悉。

建议先自己尝试去写出相关的正则表达式,再回来看下面的参考答案。

匹配Email地址的正则表达式匹配网址URL的正则表达式匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线)匹配国内电话号码(0571-87655322,001-87666622,920-209642-964)匹配腾讯qq号匹配中国邮政编码(6位数字)匹配身份证(15位或18位)匹配ip地址形如"carcar"或"barbar"等会重复的三个字符的单词==============分隔符==============

现在来看参考答案:

匹配Email地址的正则表达式:

w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*匹配网址URL的正则表达式:[a-zA-z]+://[^s]*匹配帐号是否合法(字母开头,允许5-16字母,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$匹配国内电话号码,格式为:区号-号码-分机号,分机号可能没有。d{3,4}-d{7,8}-d{3,4}|d{3,4}-d{7,8}匹配腾讯qq号:[1-9][0-9]{4,}匹配中国邮政编码(6位数字):[1-9]d{5}(?!d)匹配身份证(15位或18位):d{15}|d{18}匹配ip地址:d+.d+.d+.d+形如"carcar"或"barbar"等会重复的三个字符的单词(w{3})(1)获取以"密码:"开头的数字:(?<=密码.)d+6. 正则表达式Cheatsheet

建议收藏和下载这个cheatsheet,在必要的时候查询。

如果对你有帮助,请给我点赞,并点在看,谢谢!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
显示评论内容(2)
  1. 落幽指2023-12-31 05:00落幽指[澳门网友]103.225.87.119
    @云中天使哈哈以写爬虫就可以轻松搞定了学习了学习了!
    顶0踩0
  2. 云中天使2023-11-06 16:36云中天使[吉林省网友]27.115.96.91
    这篇文章太强了正则表达式简直不是对手!
    顶3踩0
相关阅读
「篮球短剧」保罗乔治:法官大人 库里他欺负我!from 篮球老幺

「篮球短剧」保罗乔治:法官大人 库里他欺负我!from 篮球老幺

大家好我是篮球老幺,篮球短剧场继续开播

2018-02-18

NeurIPS’20大意了没有闪 被一句话超短摘要偷袭1900篇论文!

NeurIPS’20大意了没有闪 被一句话超短摘要偷袭1900篇论文!

塔焖问我NeurIPS 2020还两个星期就要召开啦,可是收录的1900篇论文,塔焖怎么读都读不完了~我说这个问题嫩们算是问对人了,因为陈老师我作为浑元形意AI

2010-12-03

文案怎么“说人话”?5招让你文案瞬间接地气!

文案怎么“说人话”?5招让你文案瞬间接地气!

2、也有一些文案,你刚看一段,就看不下去了,感觉就像···你在口渴的时候,让你啃馒头,堵得慌

2023-06-16

写文章没话写?别怕 我教你几招搞定它!

写文章没话写?别怕 我教你几招搞定它!

比如,我在写之前就确定此文的目的是:让觉得写文章难的人,有话写

2024-01-17