二、正则表达式基础

这一节的两个表格来自于 learn-regex-zh 这个关于正则表达式项目,其使用 MIT 开源许可协议。这里只是介绍正则表达式的基本用法,需要系统学习的读者可参考 正则表达式必知必会 一书。

1. 一般字符的匹配

正则表达式是一种按照某种正则模式,从左到右匹配字符串中内容的一种工具。对于一般的字符而言,它可以找到其所在的位置,这里为了演示便利,使用了 pythonre 模块的 findall 函数来匹配所有出现过但不重叠的模式,第一个参数是正则表达式,第二个参数是待匹配的字符串。例如,在下面的字符串中找出 apple

In [28]: import re
In [29]: re.findall(r'Apple', 'Apple! This Is an Apple!')
Out[29]: ['Apple', 'Apple']

2. 元字符基础

元字符 描述
. 匹配除换行符以外的任意字符
[ ] 字符类,匹配方括号中包含的任意字符。
[^ ] 否定字符类,匹配方括号中不包含的任意字符
* 匹配前面的子表达式零次或多次
+ 匹配前面的子表达式一次或多次
? 匹配前面的子表达式零次或一次
{n,m} 花括号,匹配前面字符至少 n 次,但是不超过 m 次
(xyz) 字符组,按照确切的顺序匹配字符xyz。
| 转义符,它可以还原元字符原来的含义
^ 匹配行的开始
$ 匹配行的结束
In [30]: re.findall(r'.', 'abc')
Out[30]: ['a', 'b', 'c']
In [31]: re.findall(r'[ac]', 'abc')
Out[31]: ['a', 'c']
In [32]: re.findall(r'[^ac]', 'abc')
Out[32]: ['b']
In [33]: re.findall(r'[ab]{2}', 'aaaabbbb') # {n}指匹配n次
Out[33]: ['aa', 'aa', 'bb', 'bb']
In [34]: re.findall(r'aaa|bbb', 'aaaabbbb')
Out[34]: ['aaa', 'bbb']
In [35]: re.findall(r'a\\?|a\*', 'aa?a*a')
Out[35]: ['a', 'a', 'a', 'a']
In [36]: re.findall(r'a?.', 'abaacadaae')
Out[36]: ['ab', 'aa', 'c', 'ad', 'aa', 'e']

3. 简写字符集

此外,正则表达式中还有一类简写字符集,其等价于一组字符的集合:

简写 描述
\w 匹配所有字母、数字、下划线: [a-zA-Z0-9_]
\W 匹配非字母和数字的字符: [^\w]
\d 匹配数字: [0-9]
\D 匹配非数字: [^\d]
\s 匹配空格符: [\t\n\f\r\p{Z}]
\S 匹配非空格符: [^\s]
\B 匹配一组非空字符开头或结尾的位置,不代表具体字符
In [37]: re.findall(r'.s', 'Apple! This Is an Apple!')
Out[37]: ['is', 'Is']
In [38]: re.findall(r'\w{2}', '09 8? 7w c_ 9q p@')
Out[38]: ['09', '7w', 'c_', '9q']
In [39]: re.findall(r'\w\W\B', '09 8? 7w c_ 9q p@')
Out[39]: ['8?', 'p@']
In [40]: re.findall(r'.\s.', 'Constant dropping wears the stone.')
Out[40]: ['t d', 'g w', 's t', 'e s']
In [41]: re.findall(r'上海市(.{2,3}区)(.{2,3}路)(\d+号)',
   ....:            '上海市黄浦区方浜中路249号 上海市宝山区密山路5号')
   ....: 
Out[41]: [('黄浦区', '方浜中路', '249号'), ('宝山区', '密山路', '5号')]