Поиск…


Основные группы захвата

Группа представляет собой раздел регулярного выражения, заключенного в круглые скобки () . Это обычно называется «суб-выражением» и служит двум целям:

  • Это делает субэкспрессией атомом, т. Е. Он будет либо соответствовать, либо терпеть неудачу, либо повторять в целом.
  • Часть текста, которую он сопоставляет, доступна в остальной части выражения и в остальной части программы.

Группы пронумерованы в двигателях регулярных выражений, начиная с 1. Традиционно максимальное число групп равно 9, но многие современные ароматы регулярных выражений поддерживают более высокие групповые подсчеты. Группа 0 всегда соответствует всему шаблону, так же, как и окружающее все регулярное выражение с помощью скобок.

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

foo(bar(baz)?) (qux)+|(bla)
   1   2       3      4

групп и их номеров

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

Группа может быть необязательной, например (baz)? выше или в альтернативной части выражения, которое не использовалось для совпадения, например (bla) выше. В этих случаях несогласованные группы просто не будут содержать никакой информации.

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


Если вы хотите получить дату и уровень ошибки в записи журнала, как этот:

2012-06-06 12:12.014 ERROR: Failed to connect to remote end

Вы можете использовать что-то вроде этого:

^(\d{4}-\d{2}-\d{2}) \d{2}:\d{2}.\d{3} (\w*): .*$

Это позволит извлечь дату записи журнала 2012-06-06 качестве группы захвата 1 и ERROR уровня ошибки в качестве группы захвата 2.

Обратные ссылки и группы, не связанные с захватом

Поскольку группы «пронумерованы», некоторые двигатели также поддерживают соответствие тому, что группа ранее сопоставляла снова.

Предполагая, что вы хотите сопоставить что-то, где два равны строкам длины три, делятся на $ вы использовали:

(.{3})\$\1

Это будет соответствовать любой из следующих строк:

"abc$abc"
"a b$a b"
"af $af "
"   $   "

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

(?:)

Они особенно полезны для повторения определенной картины любое количество раз, так как группа также может использоваться как «атом». Рассматривать:

(\d{4}(?:-\d{2}){2} \d{2}:\d{2}.\d{3}) (.*)[\r\n]+\1 \2

Это будет соответствовать двум записям журнала в смежных строках, которые имеют одну и ту же метку времени и одну и ту же запись.

Именованные группы захвата

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

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

Например, чтобы сопоставить слово ( \w+ ), заключенное в одинарные или двойные кавычки ( ['"] ), мы могли бы использовать:

(?<quote>['"])\w+\k{quote}

Это эквивалентно:

(['"])\w+\1

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

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

Синтаксический анализ файла журнала является примером более сложной ситуации, которая выигрывает от имен групп. Это общий формат журнала Apache (CLF):

127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

Следующее выражение захватывает части в названные группы:

(?<ip>\S+) (?<logname>\S+) (?<user>\S+) (?<time>\[[^]]+\]) (?<request>"[^"]+") (?<status>\S+) (?<bytes>\S+)

Синтаксис зависит от вкуса, общие из них:

  • (?<name>...)
  • (?'name'...)
  • (?P<name>...)

Обратные ссылки:

  • \k<name>
  • \k{name}
  • \k'name'
  • \g{name}
  • (?P=name)

В стиле .NET вы можете иметь несколько групп, имеющих одно и то же имя, они будут использовать блоки захвата .

В PCRE вы должны явно включить его с помощью модификатора (?J) ( PCRE_DUPNAMES ) или с помощью группы сброса ветвей (?|) . Тем не менее, будет доступно только последнее зафиксированное значение.

(?J)(?<a>...)(?<a>...)
(?|(?<a>...)|(?<a>...))


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow