匹配可以重叠。
但如果从同一位置开始发现多个匹配,请选择较短的匹配。
例如,要在字符串“abcabdcd”中找到regexp parttern “a。* d”,答案应为{“abcabd”,“abd”}。并且不应包括“abcabdcd”和“abdcd”。
答案 0 :(得分:0)
这个功能效率很低,但它解决了你的问题:
def find_shortest_overlapping_matches(pattern, line):
pat=re.compile(pattern)
n=len(line)
ret=[]
for start in xrange(0, n):
for end in xrange(start+1, n+1):
tmp=line[start:end]
mat=pat.match(tmp)
if mat is not None:
ret.append(tmp)
break
return ret
print find_shortest_overlapping_matches("a.*d", "abcabdcd")
输出:
['abcabd', 'abd']
范围假设您的模式至少包含一个字符且与空字符串不匹配。此外,您应该考虑使用?
使您的模式非贪婪地匹配,以提高性能并避免内循环。
答案 1 :(得分:0)
大多数RE引擎仅默认匹配一次RE,并且默认情况下贪婪,并且围绕它们构建的标准迭代策略倾向于在上一次匹配的 end 之后重新开始搜索。要做到这一点需要一些额外的诡计。 (这段代码是Tcl,但您应该可以用许多其他语言复制它。)
proc matchAllOverlapping {RE string} {
set matches {}
set nonGreedyRE "(?:${RE}){1,1}?"
set idx 0
while {[regexp -indices -start $idx $nonGreedyRE $string matchRange]} {
lappend matches [string range $string {*}$matchRange]
set idx [expr { [lindex $matchRange 0] + 1 }]
}
return $matches
}
puts [matchAllOverlapping a.*d abcabdcd]