Захват названных групп в regex с re.findall

Когда я пытался ответить на этот вопрос: регулярное выражение, чтобы разделить% возрастов и значений на питоне, я заметил, что мне пришлось переупорядочить группы из результата findall. Например:

data = """34% passed 23% failed 46% deferred""" result = {key:value for value, key in re.findall('(\w+)%\s(\w+)', data)} print(result) >>> {'failed': '23', 'passed': '34', 'deferred': '46'} 

Здесь результат поиска:

  • Красивый суп findAll не найти их все
  • Python BeautifulSoup Получение столбца из таблицы - индекс индекса IndexError вне диапазона
  • Python - re.findall возвращает нежелательный результат
  • Регулярное выражение Python findall *
  • Модуль Python ElementTree: как игнорировать пространство имен XML-файлов для поиска соответствующего элемента при использовании метода «найти», «найти»,
  • Почему re.findall не является конкретным в поиске триплетных элементов в строке. питон
  •  >>> re.findall('(\w+)%\s(\w+)', data) >>> [('34', 'passed'), ('23', 'failed'), ('46', 'deferred')] 

    Есть ли способ изменить / указать порядок групп, которые возвращают re.findall :

     [('passed', '34'), ('failed', '23'), ('deferred', '46')] 

    Чтобы уточнить, возникает вопрос:

    Можно ли уточнить порядок или переупорядочить группы для возврата функции re.findall?

    Я использовал приведенный выше пример для создания словаря, чтобы указать причину / пример использования, когда вы хотите изменить порядок (делая ключ как значение и значение как ключ)

    Дальнейшее уточнение:

    Чтобы обрабатывать группы в более сложных более сложных регулярных выражениях, вы можете назвать группы, но эти имена доступны, только если вы выполните re.search pr re.match. Из того, что я прочитал, findall имеет фиксированные индексы для групп, возвращаемых в кортеж. Вопрос: кто-нибудь знает, как эти индексы могут быть изменены. Это поможет упростить и интуитивно понятное управление группами.

  • Заблокировать рабочую станцию ​​Windows с помощью Python
  • Как проверить, является ли мой объект python числом?
  • Python Bool и int сравнение и индексирование в списке с булевыми значениями
  • слияние файлов xml с использованием python ElementTree
  • Декодер Python для автоматического определения переменных __init__
  • количество строк с перекрывающимися вхождениями
  • 3 Solutions collect form web for “Захват названных групп в regex с re.findall”

    Возьмите 3, основываясь на дальнейшем уточнении намерений OP в этом комментарии .

    findall прав, что findall не сохраняет именованные группы захвата (например, (?P<name>regex) ). finditer на помощь! Он возвращает отдельные совпадающие объекты один за другим. Простой пример:

     data = """34% passed 23% failed 46% deferred""" for m in re.finditer('(?P<percentage>\w+)%\s(?P<word>\w+)', data): print( m.group('percentage'), m.group('word') ) 

    За комментарий OP по моему первому ответу : Если вы просто пытаетесь изменить порядок 2-х кортежей следующим образом:

     [('34', 'passed'), ('23', 'failed'), ('46', 'deferred')] 

    … чтобы выглядеть так: отдельные элементы меняются на противоположные:

     [('passed', '34'), ('failed', '23'), ('deferred', '46')] 

    Существует простое решение: используйте понимание списка с помощью sequence[::-1] синтаксиса sequence[::-1] чтобы изменить порядок элементов отдельных кортежей:

     a = [('34', 'passed'), ('23', 'failed'), ('46', 'deferred')] b = [x[::-1] for x in a] print b 

    Как вы указали в своем втором примере, re.findall возвращает группы в исходном порядке.

    Проблема в том, что стандартный тип dict Python никак не сохраняет порядок ключей . Вот руководство для Python 2.x, которое делает его явным, но это все еще верно в Python 3.x: https://docs.python.org/2/library/stdtypes.html#dict.items

    Вместо этого вы должны использовать collections.OrderedDict :

     from collections import OrderedDict as odict data = """34% passed 23% failed 46% deferred""" result = odict((key,value) for value, key in re.findall('(\w+)%\s(\w+)', data)) print(result) >>> OrderedDict([('passed', '34'), ('failed', '23'), ('deferred', '46')]) 

    Обратите внимание, что вы должны использовать парную конструкторскую форму ( dict((k,v) for k,v in ... ), а не конструктор понимания dict ( {k:v for k,v in ...} ). Это потому, что последний строит экземпляры типа dict , которые не могут быть преобразованы в OrderedDict без потери порядка ключей … что, конечно же, вы пытаетесь сохранить в первую очередь.

    Python - лучший язык программирования в мире.