正则表达式是一些由字符和特殊符号组成的字符串,它们描􏰀述了这些字符和字符的某种重复方式,因此能按某种模式匹配一个有相似特征的字符串的集合。正则表达式为高级文本模式匹配,以及搜索-替代等功能􏰁供了基础。

元字符

元字符是正则表达式中规定的特殊代码,有特定的含义和匹配效果

常用的元字符

代码 说明
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符(包括空格,制表符(Tab),换行符,中文全角空格等)
\d 匹配数字
\b 匹配单词的开始或结束(空格、标点、换行都算是单词的分割)
^ 匹配字符串的开始
$ 匹配字符串的结束

示例:

\ba\w*\b: 匹配以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w*),最后是单词结束处(\b)

\d+: 匹配1个或更多连续的数字。这里的+是和类似的元字符,不同的是\匹配重复任意次(可能是0次),而+则匹配重复1次或更多次

\b\w{6}\b: 匹配刚好6个字符的单词

^\d{5,12}$: 匹配5位到12位数字

重复

常用的限定符(指定数量的代码)

代码 说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

示例:
Windows\d+: 匹配Windows后面跟1个或更多数字
^\w+: 匹配一行的第一个单词

反义

常用的反义代码

代码 说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

字符类

我们要想查找数字,字母或数字,空白这些很简单,直接使用元字符对应的字符集合即可实现。但是如果想要匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办?

这时我们需要在方括号[]中列出想要匹配的字符集合。如[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)。

[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)

\(?0\d{2}[) -]?\d{8}:匹配几种格式的电话号码,像(010)88886666,或022-22334455,或02912345678等

分枝条件

正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开,匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了

0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)

\\(?0\d{2}\)?[- ]?\d{8}|0\d{2}[-]?\d{8}这个表达式匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔

分组

重复单个字符在后面加上限定符就行了,如果想要重复多个字符那么就需要用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作。

(\d{1,3}.){3}:\d{1,3}匹配1到3位的数字,(\d{1,3}.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次

字符转义

使用反斜杠\来取消元字符的特殊含义

例如:deerchao\.net匹配deerchao.net,C:\\Windows匹配C:\Windows

re模块

Python 通过标准库的 re 模块支持正则表达式。

常见的正则表达式函数与方法

函数/方法 描述
re 模块的函数
compile(pattern,flags=0) 对正则表达式模式 pattern 进行编译,flags是可选标志符,并返回一个 regex 对象
re 模块的函数和 regex 对象的方法
match(pattern,string, flags=0) 尝试用正则表达式模式 pattern 匹配字符串 string,flags 是可选标志符,如果匹配成功,则返回一个匹配对象;否则返回 None
search(pattern,string, flags=0) 在字符串 string 中查找正则表达式模式 pattern 的第一次出现,flags 是可选标志符,如果匹配成功,则返回一个匹配对象;否则返回 None
findall(pattern,string[,flags]) 在字符串 string 中查找正则表达式模式 pattern 的所有出现;返回一个匹配对象的列表
finditer(pattern,string[, flags]) 和 findall()相同,但返回的不是列表而是迭代器;对 于每个匹配,该迭代器返回一个匹配对象
匹配对象的方法
split(pattern,string, max=0) 根据正则表达式 pattern 中的分隔符把字符 string 分割为一个列表,返回成功匹配的列表,最多分割 max 次(默认是分割所有匹配的地方)
sub(pattern, repl, string, max=0) 把字符串 string 中所有匹配正则表达式 pattern 的地方替换成字符串 repl,如果 max 的值没有给出,则对所有匹配的地方进行替换
group(num=0) 返回全部匹配对象(或指定编号是 num 的子组)
groups() 返回一个包含全部匹配的子组的元组(如果没有成功匹配,就返回一个空元组)

将一个正则表达式的样式编译为Python中正则表达式对象。由于正则表达式在执行过程中被多次用于比较,通过re.compile()进行预编译可以提升性能。􏰁

>>> import re
>>> p = re.compile('[a-z]+')
>>> p
<_sre.SRE_Pattern object at 0x108174df0>
>>> a = p.match('abc')
>>> a
<_sre.SRE_Match object at 0x10823c9f0>
>>> re.match(p,'abc')
<_sre.SRE_Match object at 0x10823ca58>
>>> re.match(p,'123') #匹配失败返回None
>>>
#不使用compile同样可以
>>> re.match(r'[a-z]+','abc')
<_sre.SRE_Match object at 0x10823c988>
>>> re.match(r'[a-z]+','123')

匹配对象和方法

在处理正则表达式时,除regex对象外,还有另一种对象类型-匹配对象。这些对象是在match() 或 search()被成功调用之后所返回的结果。匹配对象有两个主要方法:group() 和 groups()

group()方法返回所有匹配对象或是根据要求返回某个特定子组。
groups()返回一个包含唯一或所有子组的元组。如果正则表达式中没有子组的话, groups() 将返回一个空元组,而 group()仍会返回全部匹配对象

>>> import re
>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
>>> m
<_sre.SRE_Match object at 0x1082483e8>
>>> m.group() #返回所有匹配结果
'010-12345'
>>> m.group(0) #原始字符串
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'
>>> m.groups() #返回包含子组的元组
('010', '12345')

re.match和re.search的区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配

>>> re.match('foo', 'seafood') #匹配失败返回None
>>> re.search('foo', 'seafood') #匹配成功
<_sre.SRE_Match object at 0x10823ca58>

findall():根据正则表达式搜索字符串,返回所有符合的子字符串列表

>>> re.findall('foo', 'fooseafood')
['foo', 'foo']
>>> re.findall('foo', 'foofooseafood')
['foo', 'foo', 'foo']

findall()和 search()相似之处在于二者都执行字符串搜索,但 findall()和 match()与 search()不同之处是,findall()总返回一个列表。

切分和替换

re.split():根据正则表达式分割字符串,返回分割后的所有子字符串列表

>>> import re
>>> s = re.split(r'\s+', 'a b c')
>>> re.split(r'\s+', 'a b c')
['a', 'b', 'c']
>>> re.split(r'[\s\,\;]','a,b,c d;e')
['a', 'b', 'c', 'd', 'e']

re.subn()和re.sub()
将某字符串中所有匹配正则表达式模式的部分进行替换,用来替换的部分通常是一个字符串,但也可能是一个函数,该函数返回一个用来替换的字符串。subn()和sub()一样,但它还返回一个表示替换次 数的数字,替换后的字符串和表示替换次数的数字作为一个元组的元素返回。

>>> re.sub('[ae]', 'X', 'abcdef')
'XbcdXf'
>>> re.subn('[ae]', 'X', 'abcdef')
('XbcdXf', 2)

参考

正则表达式30分钟入门教程
Python官方文档
Python核心编程