подстроки, состоящие из максимум 2 из 3 символов - PullRequest
0 голосов
/ 12 февраля 2019

Я пытаюсь написать регулярное выражение, которое будет соответствовать всем подстрокам в строке, содержащей повторения максимум 2 символов в ['a', 'b', 'c']

Так что строка типа abcccbaaa должна иметь следующие соответствия:

ab
bc
bcc
bccc
cc
ccc
cccb
ba
baa
baaa

На данный момент у меня есть: a+a*|a+b*|a+c*|b+a*|b+b*|b+c*|c+a*|c+b*|c+c*, но это не соответствует строке типа abab.Я также попытался обернуть каждую отдельную комбинацию так: (a+a*)+, но она работает не очень хорошо.Это возможно с регулярным выражением?

1 Ответ

0 голосов
/ 13 февраля 2019

Вы искали следующее выражение: (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 (результат)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...