之所以称之为正则表达式,是因为它们可以识别正则字符串(regular string),也就是说,它们可以这样定义:”如果你给我的字符串符合规则,我就返回它”,或者是“如果字符串不符合规则,我就忽略它”。这要求快速浏览大文档,以查找像电话号码和邮箱之类的字符串是非常方便的。
注意这里我用了一个词组正则字符串,什么是正则字符串?其实就是任意可以用一系列线性规则构成的字符串,就像:
(1)字母“a”至少出现一次;
(2)后面跟着字母“b”重复5次
(3)后面再跟着字母“c”重复任意偶数次
(4)最后一位是字母“d”,也可以没有
满足上述规则的字符串有“aaaaabbbbbccccd”,"aabbbbbcc"等(有无穷多的变化)
正则表达式就是这组规则的缩写。这组规则的正则表达式如下:
aa*bbbbb(cc)*(d | )
第一次见到这个字符串时会感觉难以理解,但是当我们将其分解之后就会很清楚了:
aa*
a后面跟着的a*(读作a星)表示“重复任意次a,包括0次”。这样就可以保证字母a至少出现一次。
bbbbb
这没有什么特别的,就是5次b
(cc)*
任意偶数个字符都可以编组,这个规则使用括号两个c,然后后面跟一个星号,表示有任意次两个c(也可以是0次)
(d | )
增加一个竖线(|)在表达式里表示“这个或那个”。本例表示,“增加一个后面跟着空格d,或者只有一个空格”。这样就可以保证在字符串的结尾最多是一个后面跟着空格的d
正则表达式在实际中的一个经典应用是识别邮箱地址。虽然不同的邮箱服务器的邮箱地址的具体规则不同,但是我们还是可以创建几条通用的规则。每条规则对应的正则表达式如下下表所示:
| 规则 | 正则表达式 |
| 1.邮箱地址的第一个部分至少包含 一种内容:大写字母。小写字母, 数字0-9、点号(.)、加号(+) 或下划线(-) | [A-Za-z0-9\._+]+:这个正则表达式简写 非常智慧。例如,它用“A-Z”表示任意 A-Z的大写字母。把所有可能的序列和 符号都放在中括号(不是小括号)里 表示“括号中的符号里任何一个”。要 注意后面的加号,表示“这些符号都可以 出现多次,且至少出现一次” |
| 2.之后,邮箱地址会包含一个@符号 | @:这个符号很直接。@符号必须出现 在中间位置,有且仅有一次 |
| 3.在符号@之后,邮箱地址还必须 至少包含一个大写或小写字母。 | [A-Za-z]+可能只在域名的前半部分、 符号@后面用字母。而且,至少有 一个字母 |
| 4.之后跟一个点(.) | \.:在域名前必须含有一个点号(.) |
| 5. 最后邮箱地址用com、org、edu 、net作为结尾(实际上,顶级域 名有很多种可能,但是作为示例这 写就够了 ) | (com|org|edu|net):这样列出了邮箱 地址中可能出现在点号后面的字母序列 |
[A-Za-z0-9\._+]+@[A-Za-z]+\.(com|org|edu|net)
当我们动手开始写正则表达式的时候,最好先写一个步骤列表描述出你的目标字符串结构。还要注意一些细节的处理。比如,当你识别电话号码的时候,会考虑国家代码和分机号吗?下表中列出了一些常用的符号,这12个符号是Python的正则表达式中最常用的,可以用来查找和手机绝大多数数据类型:
| 符号 | 含义 | 例子 | 匹配结果 |
| * | 匹配前面的字符、子表达式或括号里的字符0次或多次 | a*b* | aaaaaaa,bbbbbb,aaaabbbb |
| + | 匹配前面的字符、子表达式或括号里的字符至少1次 | a+b+ | aaaaaaab,aaaabbbbb,abbbb |
| [] | 匹配任意一个字符(相当于“任选一个”) | [A-Z]* | APPLE,CAPITALS,QWERTY |
| () | 表达式编组(在正则表达式的规则里编组会优先运行) | (a*b)* | aaabaab,abaaab,ababaaaaab |
| {m,n} | 匹配前面的字符、子表达式或括号里的字符m到n次 (包含m或n) | a{2,3}b{2,3} | aabbb,aaabbb,aabb |
| [^] | 匹配任意一个不再中括号里的字符 | [^A-Z]* | apple,lowercae,qwerty |
| | | 匹配任意一个由竖线分割的字符、子表达式(注意是竖线,不是大写 字母I) | b(a|i|e)d | bad,bid,bed |
| . | 匹配任意单个字符(包括符号、数字和空格等) | b.d | bad,bd,b$d,b d |
| ^ | 指字符串开始位置的字符或子表达式 | ^a | apple,asdf,a |
| \ | 转义字符(把有特殊含义的字符转换成字面形式) | \.\|\\ | .|\ |
| $ | 经常用于在正则表达式的末尾,表示“从字符串的末端匹配”。 如果不用它,每个正则表达式实际都带着“.*”模式,只会从字符串开头 进行匹配,这个符号可以看成是^符号的反义词 | [A-Z]*[a-z]*$ | ABCabc,zzzyx,Bob |
| ?! | "不包含"。这个奇怪的组合通常放在字符或正则表达式前面,表示字符 不能出现在目标字符串里。这个符号比较难用,字符通常会在字符串的不同部位 出现,如果要在整个字符串中全部排出某个字符,就加上^和$符号 | ^((?![A-Z]).)*$ | no-caps-here,$symbols a4e fine |
本文介绍了正则表达式的概念,通过实例解释了如何使用正则表达式来定义和识别符合特定规则的字符串,如电话号码和邮箱地址。在Python中,正则表达式用于数据爬虫,尤其是提取网页上的邮箱地址。建议在编写正则表达式时,先明确目标字符串结构并关注细节处理。
4万+

被折叠的 条评论
为什么被折叠?



