Python: Группа без захвата не работает в Regex - PullRequest
3 голосов
/ 07 августа 2020

Я использую группу без захвата в регулярном выражении, например, (?:.*), но она не работает.

Я все еще могу увидеть это в результате. Как его игнорировать / не фиксировать в результате?

Код:

import re

text = '12:37:25.790 08/05/20 Something   P  LR    0.156462 sccm   Pt   25.341343 psig something-else'

pattern = ['(?P<time>\d\d:\d\d:\d\d.\d\d\d)\s{1}',
           '(?P<date>\d\d/\d\d/\d\d)\s',
           '(?P<pr>(?:.*)Pt\s{3}\d*[.]?\d*\s[a-z]+)'
          ]

result = re.search(r''.join(pattern), text)

Вывод:

>>> result.group('pr')
            
'Something   P  LR    0.156462 sccm   Pt   25.341343 psig'

Ожидаемый результат:

'Pt   25.341343 psig'

Подробнее:

>>> result.groups()
            
('12:37:25.790', '08/05/20', 'Something   P  LR    0.156462 sccm   Pt   25.341343 psig')

Ответы [ 3 ]

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

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

import re

text = 'Something   P  LR    0.156462 sccm   Pt   25.341343 psig something-else'

pattern = r'(?:.*)(?P<pr>Pt\s{3}\d*[.]?\d*\s[a-z]+)'

result = re.search(pattern, text)
print(result.group('pr'))

Вывод:

Pt   25.341343 psig

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

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

Квантификатор находится внутри названной группы, вы должны разместить его снаружи и, возможно, сделать его не жадным.

Обновленный шаблон может выглядеть так:

(?P<time>\d\d:\d\d:\d\d.\d\d\d)\s{1}(?P<date>\d\d/\d\d/\d\d)\s.*?(?P<pr>Pt\s{3}\d*[.]?\d*\s[a-z]+)

Обратите внимание на , что с текущим шаблоном номер не является обязательным, так как все кванторы являются необязательными. Вы также можете опустить {1}.

Если число после Pt не может быть пустым, вы можете обновить шаблон, используя \d+(?:\.\d+)?, сопоставив хотя бы один di git:

(?P<time>\d\d:\d\d:\d\d.\d{3})\s(?P<date>\d\d/\d\d/\d\d)\s.*?(?P<pr>Pt\s{3}\d+(?:\.\d+)?\s[a-z]+)
  • (?P<time> Группа время
  • \d\d:\d\d:\d\d.\d{3} Соответствует формату времени
  • )\s Закрыть группу и сопоставить пробельный символ
  • (?P<date> Группа дата
    • \d\d/\d\d/\d\d Сопоставить дату как шаблон
  • )\s Закрыть группу и сопоставить пробельный символ
  • .*? Соответствует любому символу, кроме символа новой строки, как минимум
  • (?P<pr> Группа pr
    • Pt\s{3} Соответствует Pt и 3 символы пробела
    • \d+(?:\.\d+)? Сопоставление 1+ цифр с необязательной десятичной частью
  • \s[a-z]+ Сопоставление символа пробела и 1+ символов az
  • ) Закрыть группу

Regex demo

0 голосов
/ 07 августа 2020

Я думаю, что здесь есть путаница относительно значения термина «не захват»: это не означает, что в результате отсутствует эта часть, но что в результате не создается группа совпадений.

Пример, где одно и то же регулярное выражение выполняется с захватом и группой без захвата:

>>> import re
>>> match = re.search(r'(?P<grp>foo(.*))', 'foobar')
>>> match.groups()
('foobar', 'bar')
>>> match = re.search(r'(?P<grp>foo(?:.*))', 'foobar')
>>> match.groups()
('foobar',)

Обратите внимание, что match.group(0) одинаково в обоих случаях (группа 0 содержит совпадающую часть строки полностью).

...