新版本
您无需使用正则表达式编写任何显式循环即可解决此问题。正如@abhijith-pk's answer 巧妙地建议的那样,您可以只搜索第一个字符,其余的被放置在正向前瞻中,这将允许您进行重叠匹配:
def count_overlapping(string, pattern):
regex = '{}(?={})'.format(re.escape(pattern[:1]), re.escape(pattern[1:]))
# Consume iterator, get count with minimal memory usage
return sum(1 for _ in re.finditer(regex, string))
[IDEOne Link]
将[:1] 和[1:] 用于索引允许函数无需特殊处理即可处理空字符串,而将[0] 和[1:] 用于索引则不会。
旧版
您始终可以使用str.find 允许您指定起始索引的事实编写自己的例程。此例程效率不高,但应该可以:
def count_overlapping(string, pattern):
count = 0
start = -1
while True:
start = string.find(pattern, start + 1)
if start < 0:
return count
count += 1
[IDEOne Link]
用法
两个版本返回相同的结果。示例用法是:
>>> mystr = '^_^_^-_-'
>>> count_overlapping(mystr, '^_^')
2
>>> count_overlapping(mystr, '-_-')
1
>>> count_overlapping(mystr, '')
9
>>> count_overlapping(mystr, 'x')
0
请注意,空字符串被发现len(mystr) + 1 次。我认为这在直觉上是正确的,因为它有效地介于每个角色之间和周围。