正则表达式

Posted on 2016-08-05

还记得那句流传在程序员中古老笑话么?如果让你用正则表达式解决一个问题,那么这就会变成两个问题。

正则表达式

正则表达式看起来总是用到一些无意义的符号,让人郁闷到还不如用一些复杂点的搜索性/过滤性的方法,這里尽量用简单的语句,结合例子来讲。

正则表达式之所以叫正则表达式,是因为它总被用来确定常规字符串,对于符合规则的字符串,我们保留,反之舍弃,这对于海量文本的搜索行之有效。

我们不妨制定以下规则:

  1. 至少出现了一次字母’a’
  2. 后接字母’b’五次
  3. 后接偶数次字母’c’
  4. 可以以字母’d’结尾(也可以不用’d’结尾)

那么像“aaaabbbbbccccd,” “aabbbbbcc,” 这将如何做到呢?

aa*bbbbb(cc)*(d | )

还是看不懂怎么办?我逐句给你解释:

aa*


先说a吧,a确保出现了任意次数的’a’(包括0次),为了确保至少一次,我们写成aa*

bbbbb


这很简单,就是五次连续的’b’

(cc)*


你可以将’cc’看成一个集合,或者字母对,要求出现偶数次的话,结合a*的例子,应该不难懂。

(d|)


’|’这个符号的意思呢,是可以是左边的东西,也可以是右边的东西,这里右边是空符,也就合乎规则了。相当于或运算。

推荐大家使用 Regexpal这一在线网站来练习正则表达式的运用。

一个最经典的案例,确定一篇文档内所有的邮箱地址,该怎么做呢?

首先我们要思考邮箱地址遵循的规则是什么?

规则一

邮箱的@之前的部分一般由以下部分组成:

  • 大写字母A~Z
  • 小写字母a~z
  • 数字0~9
  • 点(.)
  • 加号(+)
  • 下划线(_)

    [A-Za-z0-9._+]+

  • 可以看懂么?注意方括号外的+是用来拼接后续字符串的。
规则二

所有的邮箱地址都包含@。出现在中间,且只能出现一次

规则三

邮箱域名必须至少包含一次大写/小写字母

[A-Za-z]+ ##### 规则四 域名中必须包含(.)

\.
规则五

邮箱地址必须以com/org/edu/net等结尾。

(com|org|edu|net)

总结一下:

[A-Za-z0-9\._+]+@[A-Za-z]+\.(com|org|edu|net)

大繁至简应如是吧

下面说一些常用的

符号 匹配内容 例子 支持匹配
* 匹配重复任意次,含0次 a*b* aaaaaaaa,aaabbbbb, bbbbbb
+ 匹配重复至少1次 a+b+ a+b+
[] 匹配括号内的任意字符 [A-Z]* APPLE,CAPITALS
() 表达式编组, 在regex的规则里编组会优先运行 (ab) aaabaab, abaaab,ababaaaaab
{m,n } 重复m到n次 a{2,3}b{2,3} aabbb, aaabbb,aabb
[^] 匹配一个任意不在方括号中的字符 [^A-Z]* apple,lowercase
| 表示或符 b(a|i|e)d bad,bid,bed
. 匹配任意单个字 b.d bad, bzd, b d
^ 标识字符串的开始 ^a apple,asdsde,a
\ 转义字符 \.\|\\ .|\
$ 标识字符串的结尾 [A~Z]*[a~z]*$ ABCabc, zzzyx, Bob

正则表达式BeautifulSoup中的运用

还记得上篇博文用到的网址么?传送门 如果我们想抓取所有的产品图片,也许会直接用img标签,如findAll(‘img’),然而对于很多网站而言,页面可能包含隐藏的图片,比如logo,或者用于称底儿的背景图,留白图等等,你就无法精确抓取你要的图片了。如果我们不通过定位图片位置的做法来,直接采用正则表达式该怎么做呢?

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re

html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bsObj = BeautifulSoup(html, "html.parser")
images = bsObj.findAll("img", {"src":re.compile("\.\.\/img\/gifts/img.*\.jpg")})
for image in images: 
    print(image["src"]) 结果如下:

../img/gifts/img1.jpg
../img/gifts/img2.jpg
../img/gifts/img3.jpg
../img/gifts/img4.jpg
../img/gifts/img6.jpg
获取全部属性

对于标签对象, 可采用.attrs获取全部属性, 返回字典对象.

imgTag.attrs["src"]

就可以获取图片的资源位置。


蚊子再小也是肉~
本站总访问量 本站访客数