Подтвердить что ты не робот

Почему не работает группа с регулярным выражением "без захвата"?

В приведенном ниже фрагменте не захватывающая группа "(?:aaa)" должна игнорироваться в результате сопоставления,

Результат должен быть только "_bbb".

Тем не менее, я получаю "aaa_bbb" в результате сопоставления; только когда я указываю group (2), он показывает "_bbb".

>>> import re
>>> s = "aaa_bbb"
>>> print(re.match(r"(?:aaa)(_bbb)", s).group())

aaa_bbb
4b9b3361

Ответ 1

group() и group(0) вернут все совпадения. Последующие группы являются фактическими группами захвата.

>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(0))
aaa_bbb
>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(1))
_bbb
>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(2))
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IndexError: no such group

Если вы хотите использовать то же поведение, что и group():

" ".join(re.match(r"(?:aaa)(_bbb)", string1).groups())

Ответ 2

Я думаю, вы неправильно понимаете концепцию "не захватывающей группы". Текст, сопоставляемый группой, не участвующей в записи, по-прежнему становится частью общего соответствия регулярному выражению.

И регулярное выражение (?:aaa)(_bbb), и регулярное выражение (aaa)(_bbb) возвращают aaa_bbb в качестве общего соответствия. Разница в том, что первое регулярное выражение имеет одну группу захвата, которая возвращает _bbb как совпадение, тогда как второе регулярное выражение имеет две группы захвата, которые возвращают aaa и _bbb в качестве их соответствующих совпадений. В вашем коде Python для получения _bbb вам нужно будет использовать group(1) с первым регулярным выражением и group(2) со вторым регулярным выражением.

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

Если вы действительно хотите исключить aaa из общего соответствия регулярному выражению, вам нужно использовать lookaround. В этом случае положительный lookbehind делает трюк: (?<=aaa)_bbb. С помощью этого регулярного выражения group() возвращает _bbb в Python. Не требуется групп захвата.

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

Ответ 3

TFM:

class re.MatchObject

group([group1, ...])

Возвращает одну или несколько подгрупп совпадения. Если есть один аргумент, результатом будет одиночная строка; если есть несколько аргументов, результатом является кортеж с одним элементом для каждого аргумента. Без аргументов, group1 по умолчанию равен нулю (возвращается весь матч). Если аргумент groupN равен нулю, соответствующее возвращаемое значение будет всей совпадающей строкой.

Ответ 4

Try:

print(re.match(r"(?:aaa)(_bbb)", string1).group(1))

group() совпадает с group(0), а группа 0 всегда присутствует и соответствует целиком RE.

Ответ 5

Вы должны указать group(1), чтобы получить только часть, захваченную скобкой (_bbb в этом случае).

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

Ответ 6

Используйте метод групп в объекте match вместо группы. Он возвращает список всех буферов захвата. Групповой метод без аргумента возвращает полное соответствие регулярного выражения.