регулярное выражение с повторяющимися именами групп - PullRequest
1 голос
/ 06 августа 2020

Я пытаюсь создать регулярное выражение, в котором у меня есть несколько повторяющихся имен групп, например, в приведенном ниже примере я хочу найти значения ph, A и B, чтобы, если я их заменю в pattern я получаю string. Я делаю это, используя regex, поскольку библиотека re по умолчанию из Python не позволяет дублировать имена.

pattern = '(?P<ph>.*?) __ (?P<A>.*?) __ (?P<B>.*?) __ \( (?P<ph>.*?) \-> (?P<A>.*?) = (?P<B>.*?) \) \)'
string = 'y = N __ ( A ` y ) __ ( A ` N ) __ ( y = N -> ( A ` y ) = ( A ` N ) ) )'
match = regex.fullmatch(pattern, string)
for k, v in match.groupdict().items():
    print(f'{k}: {v}')

И я получаю ожидаемый результат:

ph: y = N
A: ( A ` y )
B: ( A ` N )

Меня беспокоит то, что с этой библиотекой есть какие-то проблемы или я не использую ее должным образом. Например, если я заменю string на: string = 'BLABLA __ ( A ` y ) __ ( A ` N ) __ ( y = N -> ( A ` y ) = ( A ` N ) ) )'

, то приведенный выше код предоставит точно такие же значения для ph, A и B, игнорируя префикс BLABLA в начало string, а match должно быть None, так как решений нет.

Есть идеи?

Примечание: точнее, в моих задачах у меня есть пары шаблонов / строк (p_0, s_0) ... (p_n, s_n) и мне нужно найти допустимое совпадение в этих парах, поэтому я объединил их вместе с помощью разделителя __, но мне также любопытно, есть ли правильный способ сделать это.

1 Ответ

1 голос
/ 06 августа 2020

Так как вы хотите убедиться, что первые три группы равны соответствующим следующим трем группам, вам необходимо использовать обратные ссылки для первых трех групп, а не снова использовать группы захвата с одинаковыми именами:

^(?P<ph>.*?) __ (?P<A>.*?) __ (?P<B>.*?) __ \( (?P=ph) \-> (?P=A) = (?P=B) \) \)$

См. Демонстрацию регулярного выражения

Здесь (?P=ph), (?P=A) и (?P=B) - это именованные обратные ссылки которые соответствуют тому же тексту, который записан в группы с соответствующими именами.

Якоря ^ и $ не нужны в вашем коде, поскольку вы используете метод regex.fullmatch, но они вам понадобятся, когда вы протестируйте свой шаблон онлайн в тестере регулярных выражений.

...