匹配可以重叠。
但是,如果从同一位置开始发现多个匹配项,则选择短的一个。
例如,要在字符串中查找regexp parttern “a.*d”“abcabdcd”,答案应该是{"abcabd","abd"}。“abdcd”和"abdcd"不应包括在内。
发布于 2012-02-20 01:47:11
在默认情况下,大多数RE引擎只匹配RE一次,而且围绕它们构建的标准迭代策略往往在上一次匹配结束后重新启动搜索。除此之外,还需要一些额外的诡计。(这段代码是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]
发布于 2012-02-20 01:27:50
这个函数效率很低,但它解决了您的问题:
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']
范围假定您的模式至少包含一个字符,并且不匹配空字符串。此外,您应该考虑使用?
使您的模式不贪婪地匹配,以提高性能并避免内部循环。
https://stackoverflow.com/questions/9358532
复制相似问题