Получение сопоставления с шаблоном из объекта сопоставления

Я работаю с регулярным выражением Python и пытаюсь сопоставить шаблон с объектом соответствия, а не с текстом, совпадающим с самим собой.

У меня есть несколько шаблонов для замены, и я делаю это:

import re

patterns = {
    r'^[ |\n]+': '',
    r'[ |\n]+$': '',
    r'[ |\n]+': ' '
}

text = ' Hello there,  I\n need your help  here    plase :) '
text = re.sub('|'.join(patterns.keys()),
              lambda match: patterns[ match.group(0) ],
              text)

Но это неправильное решение, потому что match.group(0) возвращает совпадающий текст, поэтому ни один из них не будет равен какому-либо ключу шаблонов dict.

Я попробовал match.pattern, но получил исключение и попробовал match.re, но это дает весь объект re.compile, и его шаблон для этой проблемы - '^[ |\n]+|[ |\n]+$|[ |\n]+'.

EDIT: на основе решения Barmar я получил следующее:

import re

patterns = [
    (r'^[ |\n]+', ''),
    (r'[ |\n]+$', ''),
    (r'[ |\n]+', ' ')
]

def getreplacement(match):
    for i, group in enumerate(match.groups()):
        if group:
            return patterns[ i ][ 1 ]

text = ' Hello there,  I\n need your help  here    plase :) '
text = re.sub('|'.join('(' + p[ 0 ] + ')' for p in patterns), getreplacement, text)
print(text)

Но все же это не способ всегда получать шаблон из группы соответствия.


person Jose Ariel Romero    schedule 25.10.2019    source источник
comment
Сопоставленный шаблон будет полным выражением регулярного выражения, включающим чередование.   -  person juanpa.arrivillaga    schedule 26.10.2019
comment
@juanpa.arrivillaga Он хочет знать, какая альтернатива совпала.   -  person Barmar    schedule 26.10.2019
comment
@juanpa.arrivillaga В основном мне нужна группа объектов сопоставления, которая соответствует шаблону.   -  person Jose Ariel Romero    schedule 26.10.2019


Ответы (1)


Я не думаю, что есть способ напрямую узнать, какая альтернатива совпала.

Используйте список вместо словаря и поместите каждый шаблон в группу захвата. Затем вы можете увидеть, какая группа захвата совпала, и использовать ее в качестве индекса для получения соответствующей замены.

Обратите внимание, что это не сработает, если в шаблонах есть группы захвата. Если нужны группы, убедитесь, что они не захватывают.

import re

patterns = [
    (r'^[ |\n]+', ''),
    (r'[ |\n]+$', ''),
    (r'[ |\n]+', ' ')
]

def getreplacement(match):
    for i in range(1, match.groups):
        if match.group(i):
            return patterns[i-1][1]

text = ' Hello there,  I\n need your help  here    plase :) '
text = re.sub('|'.join('(' + p[0] + ')' for p in patterns), getreplacement, text)
person Barmar    schedule 25.10.2019
comment
Вроде работает, но я внес некоторые изменения. Также интересно, есть ли какое-нибудь встроенное решение, лучше, если это будет O(1). - person Jose Ariel Romero; 26.10.2019