Почему группа захвата имени не фиксирует одно и то же значение?

^(?'a'1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.(?&a)$

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

что не так с моим регулярным выражением?

это работает, если я повторно использую тот же шаблон

^(?:1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.(?:1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$

но это не работает, когда я пытаюсь использовать группу захвата имени (?&a)

Какой язык/инструмент вы используете?

Toto 24.07.2019 11:35

это регулярное выражение PCRE(php)

ZP. Hin 24.07.2019 11:36

Как вы это проверяете? Он работает с perl и в Notepad++. Но это не работает с php или в regex101.

Toto 24.07.2019 11:45

я тестирую его на regex101

ZP. Hin 24.07.2019 11:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
4
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Как ни странно, кажется, что подпрограмма проверяется атомарно. По сути, часть 255. соответствует нормально (хотя вы должны заменить . на \., чтобы явно захватить точку, а не любой символ), но сопоставление 255 с группой a соответствует 25 при первой возможности (1?[0-9]?[0-9]), но $ терпит неудачу, и это откатывается через всю подпрограмму вместо того, чтобы пробовать другие возможности. Решением будет изменить ваши возможности, чтобы поставить 25[0-5] на первое место.

Шаблон

^(?'a'25[0-5]|1?[0-9]?[0-9]|2[0-4][0-9])\.(?&a)$

работает на меня.

я попробовал ваше решение, но затем оно не захватило 200-249 после того, как я переместил 2[0-4][0-9] на задний план

ZP. Hin 24.07.2019 11:49

Ах, тогда подпрограмма рассматривает только первую возможность. Странно, но тут ничего не сделаешь. Попробуйте ^(?'a'2([0-4][0-9]|5[0-5]|1?[0-9]?[0-9]))\.(?&a)$ может быть?

user9658871 24.07.2019 11:52

Я скажу это просто; твой 1?[0-9]?[0-9] раздражает. Разбейте все это на ^(?'a'1[0-9][0-9]|2[0-4][0-9]|25[0-5]|[0-9][0-9]|[0-9])\.(?&‌​a)$, и у вас все получится. Похоже, эта проблема связана с подпрограммой и управлением чередованием в вашем двигателе. Nvm, решение Казимира лучше.

user9658871 24.07.2019 12:05
Ответ принят как подходящий

Это зависит от версии PCRE. С Новости ПКРЕ 10:30:

The new implementation allows backtracking into recursive group calls in patterns, making it more compatible with Perl, and also fixes some other previously hard-to-do issues.

  • До версии PCRE v10.30: изначально рекурсивный групповой вызов по умолчанию был атомарным.

    Порядок вашего чередования является ловушкой, потому что побеждает первая удачная альтернатива. В вашем случае 1?[0-9]?[0-9] соответствует 25 (другие альтернативы никогда не проверяются), тогда, когда механизм регулярных выражений пытается $ и терпит неудачу, откат в группе невозможен. Вы можете решить проблему, написав свой именованный захват следующим образом:

    (?<a>1[0-9]{0,2}|[3-9][0-9]?|2(?:[0-4][0-9]?|5[0-5]?|[6-9])?|0)
    

    это немного длиннее, но каждое число следует уникальному пути к успеху: демо

  • Начиная с PCRE 10.30: в более новой версии PCRE рекурсивные групповые вызовы больше не являются атомарными (возможен возврат, как в Perl), и ваш шаблон работает так: https://3v4l.org/HUICY

Обратите внимание, что на самом деле regex101 и PHP < 7.3 используют более старые версии PCRE, в которых рекурсивные групповые вызовы всегда являются атомарными.

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