Вы искали следующее выражение: (a + | b + | c +) {2}
Проблема в том, что re.findall () не будет перекрывать совпадающие шаблоны так:
re.findall("(a+|b+|c+){2}","abcccbaaa")
найдет только последовательные (не перекрывающиеся) совпадения: «ab», «cccb» и «aaa».(т. е. поскольку первое «b» является частью совпадения «ab», оно не считается для совпадения «bc»)
Чтобы получить все перекрывающиеся шаблоны, вам необходимо выполнить re.match () итеративно в вашей строке, удаляя символы до первого символа каждого соответствия и выполняя re.match () для остальных, пока вы не найдете больше совпадений.Вам также нужно будет применять поиск рекурсивно для больших совпадений, поскольку они могут также содержать меньшие шаблоны совпадений (например, bccc содержит bcc и bc).Наконец, вы, возможно, захотите удалить дубликаты из результата (например, ccc - это фактически два перекрывающихся шаблона cc).
Я не думаю, что вы сможете сделать это в пределах одного регулярного выражения, но вы могли бысделайте это в итерационной функции:
import re
def multiMatch(pattern,string):
result = []
match = re.match(pattern,string)
while match:
subString = string[match.start():match.end()]
result.append(subString)
result += multiMatch(pattern,subString[:-1]) # see note below
string = string[match.start()+1:]
match = re.match(pattern,string)
return list(set(result))
sorted(multiMatch("(a+|b+|c+){2}","abcccbaaa"))
>>> ['aa', 'aaa', 'ab', 'ba', 'baa', 'baaa', 'bc', 'bcc', 'bccc', 'cb', 'cc', 'ccb', 'ccc', 'cccb']
примечание: на этом этапе вам нужно только проверять меньшие шаблоны из начала подстроки.Я был ленив и просто вызывал функцию рекурсивно, но это не оптимально, так как она будет генерировать подстроки, которые будут снова перехватываться основным циклом, чтобы быть исключенными списком (set (результат)).