Именное регулярное выражение обратная ссылка в PHP

Используя регулярные выражения PHP 5.5+, я бы хотел использовать именованные обратные ссылки для захвата группы.

Например, я хотел бы, чтобы следующие тексты соответствовали:

1-1
2-2

но не следующее

8-7

Однако когда я пытаюсь использовать обратные ссылки, PHP помечает его как найденное совпадение:

/* This statement evaluates to 1 */
preg_match("/(?<one>[1-9])\-(?<two>\\g<one>)/", "8-7");

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

1 ответ

Решение

Смотрите этот отрывок из документации PCRE:

Для совместимости с Oniguruma, синтаксис не Perl \g за которым следует имя или число, заключенное в угловые скобки или одинарные кавычки, является альтернативным синтаксисом для ссылки на подшаблон в качестве подпрограммы, возможно, рекурсивно.

Обратите внимание, что \g{...} (Синтаксис Perl) и \g<...> (Синтаксис Онигурума) не являются синонимами. Первый является обратной ссылкой; последний вызов подпрограммы.

Используя \g<one>, вы ссылаетесь не на совпадение, а на подшаблон, см. объяснение на regex101.com.

\g<one> рекурсивно подшаблон one

Вам нужно использовать \1 фактически соответствовать тому же тексту, захваченному в первой группе.

(?<one>[1-9])\-(?<two>\1)

Или (именованная обратная ссылка на фактический текст),

(?<one>[1-9])\-(?<two>\g{one})

\1 соответствует тому же тексту, который был найден последней группой 1-го захвата

Посмотрите пронумерованную демонстрацию и названную демонстрацию обратной ссылки.

Другие вопросы по тегам