^(?'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)
это регулярное выражение PCRE(php)
Как вы это проверяете? Он работает с perl и в Notepad++. Но это не работает с php или в regex101.
я тестирую его на regex101






Как ни странно, кажется, что подпрограмма проверяется атомарно.
По сути, часть 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] на задний план
Ах, тогда подпрограмма рассматривает только первую возможность. Странно, но тут ничего не сделаешь. Попробуйте ^(?'a'2([0-4][0-9]|5[0-5]|1?[0-9]?[0-9]))\.(?&a)$ может быть?
Я скажу это просто; твой 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, решение Казимира лучше.
Это зависит от версии 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, в которых рекурсивные групповые вызовы всегда являются атомарными.
Какой язык/инструмент вы используете?