正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
Python 自1.5版本起增加了re 模块,re模块使Python语言拥有全部的正则表达式功能。
1. 常见正则表达式:
1.1 字符类
[aeiou] | 匹配中括号内的任意一个字母 |
[0-9] | 匹配任何数字。等价于[0123456789]或\d |
[a-z] | 匹配任何小写字母 |
[A-Z] | 匹配任何大写字母 |
[a-zA-Z0-9] | 匹配任何字母及数字 |
[^aeiou] | 除了aeiou字母以外的所有字符 |
[^0-9] | 匹配除了数字外的字符。等价于\D |
例:
[Pp]ython | 匹配 "Python" 或 "python" |
rub[ye] | 匹配 "ruby" 或 "rube" |
1.2 特殊字符类
. | 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。 |
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。空白字符即没有东西显示的字符。 |
\w | 匹配包括下划线的任何字母、数字或下划线。等价于'[A-Za-z0-9_]'。 |
\W | 匹配任何非字母、数组或下划线。等价于 '[^A-Za-z0-9_]'。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
\B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
\A | 匹配字符串开始。 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
\z | 匹配字符串结束。 |
\G | 匹配最后匹配完成的位置。 |
\n, \t等 | 匹配一个换行符、一个制表符等。 |
\1, \2等 | 匹配第n个分组的内容。 |
1.3 其他特殊字符
备注:re表示任意一个正则表达式。
re* | 匹配0个或无限多个*前的表达式。*和+的区别在于*为至少0个,+为至少1个。 |
re? | 匹配0个或1个由前面的正则表达式定义的片段。最多匹配1个,不能大于1个。相当于re{0,1}。 |
re+ | 匹配1个或无限多个+前的表达式。 |
re{n} | 精确匹配n个前面表达式。 |
re{n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
^ | 匹配字符串的开头。不在中括号中的时候的意思。在中括号中^表示不在[]中的字符。 |
[^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
$ | 匹配字符串的末尾。 |
1.4 例子
例1: re*, re+, re? 三者的区别
>>>import re
>>>match = re.match(r'\d?', '123456dogcatdog', re.I)
>>>match.group(0)
Out[31]: '1'
>>>match = re.match(r'\d+', '123456dogcatdog', re.I)
match.group(0)
Out[33]: '123456'
>>> match = re.match(r'\d*', '123456dogcatdog', re.I)
match.group(0)
Out[29]: '123456'
例2: re*, re+, re? 三者的区别
>>>import re
>>>match = re.match(r'\d*\w', 'dogcatdog', re.I) # 匹配成功,\d*匹配数字有0个也算匹配成功
>>>match.group(0)
Out[39]: 'd'
>>>match = re.match(r'\d?\w', 'dogcatdog', re.I) # 匹配成功,\d?匹配0-1个数字
>>>match.group(0)
Out[47]: 'd'
>>>match = re.match(r'\d+\w', 'dogcatdog', re.I) # 未匹配成功,因为\d+要求至少有一个数字。
>>>match.group(0)
AttributeError: 'NoneType' object has no attribute 'group'
例3: re{n} 和 re{n, m} 的用法
>>>import re
>>>match = re.match(r'\w{3}', 'dogcatdog', re.I) # r'\w{3}' 匹配长度为3的由字母/数字/下划线组成的字符串
>>>match.group(0)
Out[50]: 'dog'
>>>match = re.match(r'\w{3,6}', 'dogcatdog', re.I) # r'\w{3,6}' 匹配长度为3-6的字符串,贪心,即匹配的越长越好
>>>match.group(0)
Out[52]: 'dogcat'
2. 正则表达式处理函数
Python中常用的正则表达式处理函数有:re.match(), re.search(), re.findall(), re.sub(),使用前需要import re。
2.1 re.match(pattern, string, flags=0)
match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
匹配成功:返回一个匹配的对象。
匹配失败:返回None。
match的参数:
pattern 正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
re.I 使匹配对大小写不敏感。
re.L 做本地化识别(locale-aware)匹配。
re.M 多行匹配,影响 ^ 和 $。
re.S 使特殊字符" . "可以匹配包括换行在内的所有字符。
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B。
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
运行m = re.match()匹配成功后,查看匹配结果的方法:
可以使用group(num)或groups()匹配对象函数,来获取匹配到的结果。
m.group(0) # 查看匹配的整个表达式的字符串
m.group(num=n) # n>0的整数,返回第n个匹配到的字符串。
m.groups # 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
例子: 测试group
>>>import re
>>> re.match(r'dog', 'dog cat dog')
Out[21]: <_sre.SRE_Match object at 0xb743e720<
>>> match = re.match(r'dog', 'dog cat dog')
>>> match.group(0)
Out[22]: 'dog'
>>> re.match(r'cat', 'dog cat dog') # 未匹配到,因为字符串不是以cat开头
Out[23]: # 返回值为None,打印出来看什么也没有
例子: # 使用flags标志位。
>>>import re
>>>match = re.match(r'Dog', 'dog cat dog', re.I) # 匹配时忽略大小写
>>>match.group(0)
Out[27]: 'dog'
2.2 re.search(pattern, string, flags=0):
search扫描整个字符串并返回第一个成功的匹配。
注意:只返回第一个匹配!!!
m = re.search()
search的参数:
pattern 正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
例子:
>>>import re
>>> match = re.search(r'cat', 'dog cat dog')
>>> match.group(0)
Out[17]: 'cat'
例子:
>>>import re
>>>str = r'air_00a91d42b08b08d9_2017-04-23'
>>>match = re.search(r'(air_.*)_(.*)', str) # 括号括起来的内容表示处于同一组,可以用group(num)分组查看匹配结果
>>>match.group(0)
Out[18]: 'air_00a91d42b08b08d9_2017-04-23'
>>>match.group(1)
Out[19]: 'air_00a91d42b08b08d9'
>>>match.group(2)
Out[20]: '2017-04-23'
>>>match.group(3) # 报错,因为没有3
Out[21]: IndexError: no such group
2.3 re.findall(pattern, string, flags=0):
返回所有匹配成功的字符串组成的列表,返回值类型为list。
与search的区别:search只返回匹配成功的第一个字符串,而findall会将所有匹配成功的字符串都返回。
findall的参数:
pattern 正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
例子:
>>>import re
>>>re.findall(r'dog', 'dog cat dog')
Out[15]: ['dog', 'dog']
2.4 re.sub(pattern, repl, string, count=0, flags=0):
# 匹配并替换
匹配所有字符串?还是匹配一个?,然后用repl替换匹配成功的子字符串。
sub的参数:
pattern 正则表达式
repl 用repl来替换匹配到的字符串,repl也可为一个函数。
string 要匹配的字符串
count 为0表示所有匹配到的子字符串都替换为repl,为大于0的整数表示最多替换count个
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
例子:
>>>import re
>>>phone = "2004-959-559# 这是一个国外电话号码"
>>>num = re.sub(r'#.*$', "", phone) # 删除字符串中的 Python 注释
>>>print "电话号码是: ", num
Out: 电话号码是: 2004-959-559
>>>num = re.sub(r'\D', "", phone) # 将所有非数字的字符替换为空
>>>print "电话号码是 : ", num
Out: 电话号码是 : 2004959559