正则表达式匹配变长的字符:
*:匹配
前面的
子表达式0到多次。* 等价于
+:匹配
前面的
子表达式一次或多次(大于等于1次)。+等价于
?:匹配
前面的
子表达式零次或一次。等价于
{n}:n是一个非负整数。匹配确定的n次
{n,}:n是一个非负整数。至少匹配n次
{n,m}: m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。请注意在逗号和两个数之间不能有空格
?: 当该字符紧跟在任何一个其他
限制符(*,+,?,{n},{n,},{n,m})
后面时,匹配模式是非贪婪的
。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串。例如,对于字符串“oooo”,“o+”将尽可能多地匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少地匹配“o”,得到结果 ['o', 'o', 'o', 'o']
python中的re模块
有了前面的准备知识,我们就可以在 Python 中使用正则表达式了。 Python 提供
re模块
,包含所有正则表达式的功能。
由于
Python 的字符串本身也用\转义
,所以要特别注意:
s = 'ABC\\-001' # Python 的字符串
# 对应的正则表达式字符串变成:
# 'ABC\-001'
因此我们强烈建议使用 Python 的 r 前缀(这里的r前缀表示对应的python字符串中不转义.),就不用考虑转义的问题了:
s = r'ABC\-001' # Python 的字符串
# 对应的正则表达式字符串不变:
# 'ABC\-001'
小结:python的正则表达式语言也是用字符串来表示的,所以要确保得到的正则表达式字符串正确,得到正则表达式字符串后,按照正则表达式的语法进行匹配解码,在匹配解码过程中正则表达式字符串还有可能进行正则表达式的转义.
使用re.match判断是否匹配
使用re模块中的match函数表示是否匹配,
re.match函数的第一个参数为正则表达式,
第二个参数为我们要判断的字符串,
如果匹配成功的话,返回一个Match对象,否则返回None。
>>> import re
>>> re.match(r'^\d{3}\-\d{3,8}$', '010-12345')
<_sre.SRE_Match object; span=(0, 9), match='010-12345'>
常见的判断方法就是:
test = '用户输入的字符串'
if re.match(r'正则表达式', test):
print('ok')
else:
print('failed')
使用re.split切分字符串
用正则表达式切分字符串比用固定的字符更灵活,请看正常的切分代码:
>>> 'a b c'.split(' ')
['a', 'b', '', '', 'c']
无法识别连续的空格,用正则表达式试试:
>>> re.split(r'\s+', 'a b c')
['a', 'b', 'c']
使用re模块中的re.split函数进行字符串切分,
第一个参数为正则表达式,
第二个参数为我们要切分的字符串.
>>> re.split(r'[\s\,]+', 'a,b, c d')
['a', 'b', 'c', 'd']
再再试试:
>>> re.split(r'[\s\,\;]+', 'a,b;; c d')
['a', 'b', 'c', 'd']
使用re.match分组提取子串
除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组( Group)。比如:
>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
<_sre.SRE_Match object; span=(0, 9), match='010-12345'>
>>> m.group(0)
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345
如果正则表达式中定义了组,就可以在 Match 对象上用 group()方法提取出子串来,
用groups()方法提取出所有的要提取的子串出来。
注意到 group(0)永远是原始字符串,
group(1)、 group(2)……表示第 1、2、 ……个子串。
提取子串非常有用。来看一个更凶残的例子:
>>> t = '19:05:30'
re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9
]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0
-9])$', t)
>>> m.groups()
('19', '05', '30')
这个正则表达式可以直接识别合法的时间。
使用re.compile编译正则表达式
当我们在 Python 中使用正则表达式时, re 模块内部会干两件事情:
编译正则表达式,如果正则表达式的字符串本身不合法,会报错
用编译后的正则表达式去匹配字符串
如果一个正则表达式要重复使用几千次,出于效率的考虑,我们可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配:
>>> import re
# 编译:
>>> re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')
# 使用:
>>> re_telephone.match('010-12345').groups()
('010', '12345')
>>> re_telephone.match('010-8086').groups()
('010', '8086')
编译后生成 Regular Expression 对象,由于该对象自己包含了正则表达式,所以调用对应的方法时不用给出正则字符串。
正则表达式贪婪匹配
正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
由于\d+采用贪婪匹配,直接把后面的 0 全部匹配了,结果 0*只能匹配空字符串了。
必须让\d+采用非贪婪匹配(也就是尽可能少匹配,这里的尽可能少匹配指的是在能匹配的前提下尽可能少匹配),才能把后面的 0匹配出来,加个?就可以让\d+采用非贪婪匹配:
>>> re.match(r'^(\d+?)(0*)$', '102300').groups()
('1023', '00')