用python正则表达式匹配重复模式
Nov 21, 2008感谢zhenhai的莅临教导。
简单的问题:
一个字符串是”AAAAA”(5个A),我想从中找到”AAAA”的pattern有几个,怎么找?
可能有些人第一反应是findall,我起初也这么觉得,但是:
>>> import re >>> pat=re.compile(‘A{4}’) >>> m=pat.findall(‘AAAAA’) >>> m [‘AAAA’]
列表m只有一个元素,而不是我们期望的两个。
这是因为findall找到匹配的子字符串后,相当于“消费”了这些字符串,下一次的匹配就从第5个A开始查找,当然找不到。。
解决方法:
使用(?=...)
以下抄自这里
- Matches if ... matches next, but doesn't consume any of the string. This is called a lookahead assertion. For example, Isaac (?=Asimov) will match
'Isaac '
only if it's followed by'Asimov'
.
大意:仅当…匹配后面的字段时,才认为前面的字段是匹配,而与…匹配的字段不会被“消费”,仍然会被查找。
继续上面的例子:
>>> import re >>> pat=re.compile(‘A(?=AAA)’) >>> m=pat.findall(‘AAAAA’) >>> m [‘A’, ‘A’]
现在列表m的长度是2,我们找到了2个匹配。
下面有个稍微复杂的例子:
>>> pat=re.compile(‘[AT][AT][ACGT][ACGT][CG][CG]’) >>> m=pat.findall(‘ATATATCCGG’) >>> m [‘ATATCC’]
>>> pat=re.compile(‘AT’) >>> m=pat.findall(‘ATATATCCGG’) >>> m [‘A’, ‘T’, ‘A’]
另外一个解决此问题的方法是遍历字符串。
>>> indices = [m.start() for m in re.finditer(re.compile(‘AT’), ‘ATATATCCGG’)] >>> indices [2, 3, 4]
完