У меня проблемы с регулярным выражением в PHP, которое использует потенциально пустую обратную ссылку. Я надеялся, что это будет работать, как объяснено в http://www.regular -expressions.info / brackets.html :
Если обратная ссылка не использовалась в
конкретная попытка совпадения (например, в
первый пример, где вопрос
Марк сделал первую обратную ссылку
необязательно), он просто пуст. С помощью
пустая обратная ссылка в регулярном выражении
прекрасно. Это будет просто
заменен ничем.
Однако кажется, что PHP немного отличается от http://php.net/manual/en/regexp.reference.back-references.php:
Если подшаблон фактически не был
используется в конкретном матче, то любой
обратные ссылки на него всегда терпят неудачу.
В качестве упрощенного примера я хочу сопоставить следующие две вещи с этим регулярным выражением:
- {что-то} ... {/ что-то}
- {что-то: еще} ... {/ что-то: еще}
Где «что-то» известно заранее, а «еще» может быть чем угодно (или ничем).
поэтому я попробовал следующее регулярное выражение («просто» для простоты):
preg_match("/\{(something(:else)?)\}(.*?)\{\/something\\2\}/is", $data, $matches)
К сожалению, если (: else)? не совпадает, обратная ссылка \ 2 завершается неудачно. Если я сделаю \ 2 необязательным (\ 2?), То я могу сопоставить {что-то} ... {что-то: еще}, что не годится.
Я столкнулся с ограничением регулярных выражений (печально известное «вам нужен анализатор, а не регулярное выражение») или это можно исправить?
Тестовая программа:
<?php
$data = "{something} ... {/something}
{something:else} ... {/something:else}
{something:else} ... {/something}";
// won't match {something} ... {/something}
preg_match_all("/\{(something(:else)?)\}(.*?)\{\/something\\2\}/is", $data, $matches);
print_r($matches);
// change \\2 to \\2? and it matches too much
preg_match_all("/\{(something(:else)?)\}(.*?)\{\/something\\2?\}/is", $data, $matches);
print_r($matches);
?>