正则表达式为高级的文本模式匹配、抽取、与/或文本形式的搜索和替换功能提供了基础。通过标准库中的re模块来支持正则表达式。
表示法 | 描述 | 正则表达式示例 |
---|---|---|
符号 | ||
re1|re2 | 匹配正则表达式re1或者re2 | foo|bat |
. | 匹配任何字符(除了\n之外) | b.b |
^ | 匹配字符串的起始部分 | ^Dear |
$ | 匹配字符串的终止部分 | /bin/*sh$ |
* | 匹配0次或者多次前面出现的正则表达式 | [A-Za-z0-9]* |
+ | 匹配1次或者多次前面出现的正则表达式 | [a-z]+\.com |
? | 匹配0次或者1次前面出现的正则表达式 | goo? |
{N} | 匹配N次前面出现的正则表达式 | [0-9]{3} |
{M,N} | 匹配M-N次前面出现的正则表达式 | [0-9]{5,9} |
[...] | 匹配来自字符集的任意单一字符 | [aeiou] |
[...x-y...] | 匹配x-y范围内的任意单一字符 | [0-9] |
[^...] | 不匹配此字符集中出现的任何一个字符,包括某一范围的字符(如果在此字符集中出现) | [^aeiou] |
(...) | 匹配封闭的正则表达式,然后另存为子组 | ([0-9]{3})? |
特殊字符 | ||
\d | 匹配任何十进制数字,与[0-9]一致(\D与\d相反,不匹配任何非数值型的数字) | data\d+.txt |
\w | 匹配任何字母数字字符,与[A-Za-z0-9]相同(与\W)相反 | [A-Za-z]\w |
\s | 匹配任何空格字符,与[\n\t\r\v\f]相同(与\S相反) | of\she |
\b | 匹配任何单词边界(\B相反) | \bThe\b |
\A(\Z) | 匹配字符串的起始(结束) | \ADear |
如果问号紧跟在任何使用闭合操作符的匹配后面,它将直接要求正则表达式引擎匹配尽可能少的次数。
尽可能少的次数是什么意思?当模式匹配使用分组操作符时,正则表达式引擎将试图“吸收”匹配该模式的尽可能多的字符。这通常被叫做贪婪匹配。问号要求正则表达式引擎去“偷懒”,如果有可能,就在当前的正则表达式中尽可能少地匹配字符,留下尽可能多的字符给后面的模式(如果存在)。
当使用正则表达式时,一对圆括号可以实现以下任意一个(或者两个)功能:
常见的正则表达式属性
函数/方法 | 描述 |
---|---|
仅仅是re模块 | |
compile | 使用任何可选的标记来编译正则表达式的模式,然后返回一个正则表达式对象 |
re模块函数和正则表达式对象的方法 | |
match | 尝试使用带有可选的标记的正则表达式的模式来匹配字符串。如果匹配成功,就返回匹配对象;如果失败,就返回None |
search | 使用可标记搜索字符串中第一次出现的正则表达式。如果匹配成功,就返回匹配对象;如果失败就返回None |
findall | 查找字符串中所有(非重复)出现的正则表达式模式,并返回一个匹配对象 |
finditer | 与findall()函数相同,但返回的不是一个列表,而是一个迭代器。对于每一次匹配,迭代器都返回一个匹配对象。 |
split | 根据正则表达式的模式分隔符,split函数将字符串分割为列表,然后返回成功匹配的列表,分隔符最多操作MAX次(默认分割所有匹配成功的位置) |
re模块函数和正则表达式对象的方法 | |
sub | 使用repl替换所有正则表达式的模式在字符串中出现的位置,除非定义count,否则就将替换所有出现的位置 |
purge() | 消除隐式编译的正则表达式 |
常用的匹配对象 | |
group | 返回整个匹配对象,或者编号为num的特定子组 |
groups | 返回一个包含所有匹配子组的元祖(没有成功,返回空元组) |
groupdict | 返回一个包含所有匹配的命名子组的字典,所有的子组名称作为字典的键 |
常用的模块属性 | |
re.I | 不区分大小写的匹配 |
成功调用match()和search()返回的对象。
group()要么返回整个匹配对象,要么根据要求返回特定子组。groups()则仅返回一个包含唯一或者全部子组的元组。如果没有子组的要求,那么当group()仍然返回整个匹配时,groups()返回一个空元组。
match()函数试图从字符串的起始部分对模式进行匹配。
>>> re.match('foo','foo').group()
'foo'
>>> re.match('foo','food on match').group()
'foo'
>>> re.match('foo','fodo on match').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group‘
search()和match()的工作机制完全一致,不同之处在于search会用它的字符串参数,在任意位置对给定正则表达式模式搜索第一次出现匹配的情况。
>>> re.match('foo','sea food').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.search('foo','sea food').group()
'foo'
>>> bt = 'bat|bet|bit'
>>> re.match(bt,'bat').group()
'bat'
>>>
>>> re.match(bt,'bit').group()
'bit'
>>>
>>> re.match(bt,'blt').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
>>> re.match(bt,'he bit me').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
>>> re.search(bt,'he bit me').group()
'bit'
>>> anyend = '.end'
>>> re.match(anyend,'bend').group()
'bend'
>>>
>>> re.match(anyend,'end').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
>>> re.match(anyend,'\nend').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
>>> re.search('.end','The end.').group()
' end'
>>>
>>> re.match('[cr][23][dp][o2]','c3po').group()
'c3po'
>>>
>>> re.match('[cr][23][dp][o2]','c2do').group()
'c2do'
>>>
>>> re.match('r2d2|c3po','c2do').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
>>> re.match('r2d2|c3po','r2d2').group()
'r2d2'
>>>
>>> re.match('(\w\w\w)-(\d\d\d)','abc-123').group()
'abc-123'
>>> re.match('(\w\w\w)-(\d\d\d)','abc-123').group(1)
'abc'
>>> re.match('(\w\w\w)-(\d\d\d)','abc-123').group(2)
'123'
>>> re.match('(\w\w\w)-(\d\d\d)','abc-123').groups()
('abc', '123')
>>>
>>> m = re.match('ab','ab') #没有子组
>>> m.group() #完整匹配
'ab'
>>> m.groups() #所有子组
>>>
>>> m = re.match('(ab)','ab')
>>> m.group()
'ab'
>>> m.groups()
('ab',)
>>>
>>> m= re.match('(a)(b)','ab')
>>> m.group()
'ab'
>>> m.group(1) # 子组1
'a'
>>> m.group(2) #子组2
'b'
>>> m.groups()
('a', 'b')
>>>
>>> m = re.match('(a(b))','ab')
>>> m.group()
'ab'
>>> m.group(1)
'ab'
>>> m.group(2)
'b'
>>> m.groups()
('ab', 'b')
>>>
>>> m = re.search('^the','the end.')
>>> m.group()
'the'
>>>
>>> m = re.search('^the','end. the')
>>> m.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
>>> m = re.search(r'\bthe','is the yes')
>>> m.group()
'the'
>>>
>>> m = re.search(r'\bthe','isthe yes') #有边界
>>> m.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
>>> m = re.search(r'\Bthe','isthe yes') #没有边界
>>> m.group()
'the'
findall()查询字符串中某个正则表达式模式全部的非重复出现的情况。总返回一个列表。
>>> re.findall('car','car')
['car']
>>> re.findall('car','scary')
['car']
>>> re.findall('car','carry the barcardi to car')
['car', 'car', 'car']
>>>
两者几乎一样,都是将某字符串中所有匹配正则表达式的部分进行某种形式的替换。用来替换的部分通常是一个字符串,但它也可能是一个函数,该函数返回一个用来替换的字符串。subn()和sub()一样,但是subn()还返回一个表示替换的总数,替换后的字符串和表示替换总数的数字一样一起作为一个拥有两个元素的元组返回。
>>> re.sub('X','Mr.Smith','atten:X\n\nDear X,\n')
'atten:Mr.Smith\n\nDear Mr.Smith,\n'
>>> re.subn('X','Mr.Smith','atten:X\n\nDear X,\n')
('atten:Mr.Smith\n\nDear Mr.Smith,\n', 2)
>>>
>>> re.sub('[ae]','X','abcdef')
'XbcdXf'
>>> re.subn('[ae]','X','abcdef')
('XbcdXf', 2)
>>>
如果你不想为每次模式的出现都分割字符串,就可以通过为max参数设定一个值(非零)来制定最大分割数。
如果给定分隔符不是使用特殊符号来匹配多重模式的正则表达式,那么re.split()与str.split()工作方式相同,例子如下
>>> re.split(':','str1:str2:str3')
['str1', 'str2', 'str3']