Как сделать регулярное выражение python, которое соответствует нескольким шаблонам с одним и тем же индексом

Можно ли получить все перекрывающиеся совпадения, которые начинаются с одного и того же индекса, но относятся к другой группе соответствия?

например когда я ищу шаблон "(A)|(AB)" из "ABC", регулярное выражение должно возвращать следующие совпадения:

(0, "А") и (0, "АВ")


person Mikael Lepistö    schedule 23.05.2011    source источник
comment
На самом деле это все еще открыто, я не очень понимал, какие матчи я ищу. Другой пример: для AABAABA я хотел бы иметь совпадения (0,['A']), (1,['A','AB']), (3, ['A']), (4, [ 'А', 'АВ']), (6, ['А']).   -  person Mikael Lepistö    schedule 24.05.2011
comment
Эти вопросы и ответы вдвойне полезны тем, что они отвечают на два вопроса, один из которых неправильно понят, но, тем не менее, полезен.   -  person n611x007    schedule 07.04.2013


Ответы (2)


Для одной возможности см. ответ Evpok. Вторая интерпретация вашего вопроса может заключаться в том, что вы хотите сопоставить все шаблоны одновременно с одной и той же позиции. В этом случае вы можете использовать опережающее выражение. Например. регулярное выражение

(?=(A))(?=(AB))

даст вам желаемый результат (т.е. все места, где оба шаблона совпадают с группами).

Обновление: с дополнительным пояснением это все еще можно сделать с помощью одного регулярного выражения. Вам просто нужно сделать обе группы выше необязательными, т.е.

(?=(A))?(?=(AB))?(?:(?:A)|(?:AB))

Тем не менее, я бы не советовал этого делать. Вы можете гораздо проще искать каждый шаблон отдельно, а затем объединять результаты.

string = "AABAABA"
result = [(g.start(), g.group()) for g in re.compile('A').finditer(string)]
result += [(g.start(), g.group()) for g in re.compile('AB').finditer(string)]
person Howard    schedule 23.05.2011
comment
Хороший! Кажется, это именно то, что я хотел. - person Mikael Lepistö; 24.05.2011
comment
Я добавил уточняющий комментарий к вопросу. Это решение действительно дает совпадения только там, где совпадают оба шаблона. Для случая в комментарии выше это будут (1, ['A','AB']) и (4, ['A','AB']). - person Mikael Lepistö; 24.05.2011
comment
Кстати, re.compile('AB').finditer(string) действительно полезен? re.finditer('AD',string) должно помочь, или, если вы абсолютно хотите скомпилировать его заранее, выполнение этого вне понимания списка также должно работать и прояснить выражение. - person Evpok; 10.06.2011

Я понимаю это, хотя я не могу вспомнить, где и от кого

def myfindall(regex, seq):
    resultlist = []
    pos = 0
    while True:
        result = regex.search(seq, pos)
        if result is None:
            break
        resultlist.append(seq[result.start():result.end()])
        pos = result.start() + 1
    return resultlist

он возвращает список всех совпадений (даже перекрывающихся) с ограничением не более одного совпадения для каждого индекса.

person Evpok    schedule 23.05.2011
comment
В случае выше это, кажется, возвращает только «A», но не соответствует «AB». - person Mikael Lepistö; 24.05.2011
comment
Правда, совпадения без эксклюзивной части это нарушают. Кстати, stackoverflow.com/ вопросы/5616822/ работают? - person Evpok; 24.05.2011
comment
Не совсем. Я пробовал это раньше, и это не работает так, как я хотел. Он выполняет только одно совпадение для каждого индекса совпадающей строки. В итоге я написал простой синтаксический анализатор на основе таблицы поиска, так как это был довольно неприятный случай с регулярным выражением. - person Mikael Lepistö; 24.05.2011
comment
Я не знал, что у python есть отдельная функция search и что match соответствует только началу строки: docs.python.org/2/library/re.html#search-vs-match - person n611x007; 07.04.2013