Поиск…


основы

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

Например, если вы пытаетесь проверить, что строка имеет цифру от нуля до девяти, разделитель, такой как дефисы, косые черты или даже пробелы, строчная буква, другой разделитель, затем другая цифра от нуля до девяти, вы можете используйте регулярное выражение:

[0-9][-/ ][a-z][-/ ][0-9]

Это будет соответствовать 1-a-4 , но оно также будет соответствовать 1-a/4 или 1 a-4 . Если мы хотим, чтобы разделители соответствовали друг другу, мы можем использовать группу захвата и обратную ссылку. В обратной ссылке будет отображаться совпадение, найденное в указанной группе захвата, и убедитесь, что местоположение обратной ссылки соответствует точно.

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

[0-9]([-/ ])[a-z]\1[0-9]

\1 обозначает первую группу захвата в шаблоне. При этом небольшом изменении регулярное выражение теперь соответствует 1-a-4 или 1 a 4 но не 1 a-4 или 1-a/4 .

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

([0-9])([-/ ])[a-z][-/ ]([0-9])
|--1--||--2--|          |--3--|

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

(([0-9])([-/ ]))([a-z])
 |--2--||--3--|
|-------1------||--4--|

Неоднозначные обратные ссылки

Проблема: вам нужно сопоставить текст определенного формата, например:

1-a-0
6/p/0
4 g 0

Это цифра, разделитель (один из - , / или пробел), буква, тот же разделитель и нуль.

Наивное решение: адаптируя регулярное выражение из примера Basics , вы можете найти это регулярное выражение:

[0-9]([-/ ])[a-z]\10

Но это, вероятно, не сработает. Большинство разновидностей регулярных выражений поддерживают более девяти групп захвата, и очень немногие из них достаточно умны, чтобы понять, что, поскольку есть только одна группа захвата, \10 должна быть обратной ссылкой на группу 1, за которой следует буква 0 . Большинство вкусов будут относиться к ней как к обратной стороне группы 10. Некоторые из них будут вызывать исключение, потому что нет группы 10; остальные просто не совпадают.

Существует несколько способов избежать этой проблемы. Один из них - использование названных групп (и названных обратных ссылок):

[0-9](?<sep>[-/ ])[a-z]\k<sep>0

Если ваш язык регулярного выражения поддерживает его, формат \g{n} (где n - число) может заключить номер обратной ссылки в фигурные скобки, чтобы отделить его от любых цифр после него:

[0-9]([-/ ])[a-z]\g{1}0

Другим способом является использование расширенного форматирования регулярных выражений, разделение элементов на несущественные пробелы (в Java вам нужно избежать пробела в скобках):

(?x) [0-9] ([-/ ]) [a-z] \1 0

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

[0-9]([-/ ])[a-z](?:\1)0

... или фиктивный квантификатор (возможно, это единственное обстоятельство, в котором {1} полезно):

[0-9]([-/ ])[a-z]\1{1}0


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