Почему не работает группа с регулярным выражением "без захвата"?
В приведенном ниже фрагменте не захватывающая группа "(?:aaa)"
должна игнорироваться в результате сопоставления,
Результат должен быть только "_bbb"
.
Тем не менее, я получаю "aaa_bbb"
в результате сопоставления; только когда я указываю group (2), он показывает "_bbb"
.
>>> import re
>>> s = "aaa_bbb"
>>> print(re.match(r"(?:aaa)(_bbb)", s).group())
aaa_bbb
Ответы
Ответ 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 вместо группы. Он возвращает список всех буферов захвата. Групповой метод без аргумента возвращает полное соответствие регулярного выражения.