2020年5月23日 / 257次阅读 / Last Modified 2020年9月7日
re模块
python中的正则表达式,与其它编程语言所支持的正则表达式,在语法上有许多都是相同的,这个给自己做一个简单的总结,以便以后查阅。
注意\w\s\d\b对应的\W\S\D\B是相互取反的意思。
python的re模块默认执行贪婪匹配模式,即在符合正则表达式语义的情况下,尽可能多的匹配长的字串。我们也可以选择懒惰模式。
设置懒惰匹配模式,就是多加一个?号。
>>> re.search('a{2,6}?','aaaaab')
<re.Match object; span=(0, 2), match='aa'>
>>> re.search('a{2,6}','aaaaab')
<re.Match object; span=(0, 5), match='aaaaa'>
>>> re.findall('a.*?b', 'aabab')
['aab', 'ab']
>>> re.findall('a.*b', 'aabab')
['aabab']
>>>
>>> re.findall('a.*?b', 'aab')
['aab']
>>> re.findall('a.*?b', 'aaaaab')
['aaaaab']
注意以上示例代码,a.*?b是懒惰模式,但是为什么没有匹配出ab,而是把所有的a都匹配出来了呢?
简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权——The match that begins earliest wins。
表示匹配[]中的任意一个符号,用[^]来取它的反义,也可在字符集合中对部分特殊字符进行转义匹配,入上一段描述。
[abcde],匹配abcde任意一个符号;
[^abcde],匹配任意一个不是abcde的符号;^如果不在最前面,就没有特别的含义;
[(^$*?.)-],匹配这些特殊字符,不用转义;
[a-zA-Z0-9],匹配范围;[-a],匹配-或a;[a\-z],此时-不再表示范围,仅仅是它自己;
[](){}[],[()[\]{}],匹配括号;
多个规则,用|符号来分开。
>>> re.findall('\d+|\w+|\$+','123abc$$$')
['123', 'abc', '$$$']
A|B, where A and B can be arbitrary REs, creates a regular expression that will match either A or B. An arbitrary number of REs can be separated by the '|' in this way. This can be used inside groups (see below) as well. As the target string is scanned, REs separated by '|' are tried from left to right. When one pattern completely matches, that branch is accepted. This means that once A matches, B will not be tested further, even if it would produce a longer overall match. In other words, the '|' operator is never greedy. To match a literal '|', use \|, or enclose it inside a character class, as in [|].
分支不仅可以在[]中使用,还可以在()中使用,威力更大。[]中是符号集,()中是pattern集。
分组的作用,除了能够通过Match对象的group()和groups()函数来获取整个匹配串以及各个分组所匹配的子串之外,还可以对子表达式进行整个的操作,比如重复。
>>> rt = re.search('(\d+)(\w+)(\$+)','123abc$$$')
>>> rt.groups()
('123', 'abc', '$$$')
>>> rt = re.search('(\d)+(\w+)(\$+)','123abc$$$')
>>> rt.group()
'123abc$$$'
>>> rt.groups()
('3', 'abc', '$$$')
上面简单的分组采用数字编号命名,默认从1开始,我们还可以自定义分组的名称。
>>> rt = re.search('(?P<number>\d+)==(?P<letter>[a-zA-Z]+)', '123==abc')
>>> rt.group()
'123==abc'
>>> rt.group(1)
'123'
>>> rt.group(2)
'abc'
>>> rt.group('number')
'123'
>>> rt.group('letter')
'abc'
也有人说成后向引用(backreference)。正则表达式的匹配是从左到右进行的,反向(或后向),就是到左边去的意思。\number的方式,可以直接引用一个左边已经匹配的分组,number是分组号,默认从1开始,直到99.
For example, (.+) \1 matches 'the the' or '55 55', but not 'thethe' (note the space after the group). This special sequence can only be used to match one of the first 99 groups.
\b(\w+)\b\s+\1\b,可以用来匹配重复的单词,像go go, 或者kitty kitty。
当然也可以反向引用命名分组,语法为 (?P=name)
>>> rt = re.search('(?P<num>\d+)==(?P=num)', '123==123')
>>> rt.group()
'123==123'
>>> rt.group(1)
'123'
>>> rt.group('num')
'123'
>>> rt.group(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: no such group
-- EOF --
本文链接:https://www.pynote.net/archives/1970
《python正则表达式的基本语法》有2条留言
前一篇:python多线程的信号量
后一篇:python的连续赋值语句
©Copyright 麦新杰 Since 2019 Python笔记
分组()的用途,除了groups之外,在分组内使用|,或者对整个分组+*?,都很常见。 [ ]
关于back reference,并不是在右边使用与左边一样的re,而是右边完全等于左边。 [ ]