Я считаю, что preg_match_all и preg_replace не находят одинаковые совпадения на основе одного и того же шаблона.
Мой шаблон:
/<(title|h1|h2|h3|h4|h5|ul|ol|p|figure|caption|span)(.*?)><\/(\1)>/
Когда я запускаю это против фрагмента, содержащего подобные
<span class="blue"></span>
с preg_match_all я получаю 17 совпадений.
Когда я использую тот же шаблон в preg_replace, я получаю 0 совпадений. Замена \ 1 списком выбора действительно находит совпадения, но, конечно, это не сработает как решение, потому что тогда оно не гарантирует, что закрывающий тег будет того же типа, что и открывающий тег.
Общая цель состоит в том, чтобы найти экземпляры тегов без содержимого, которые не должны присутствовать без содержимого … священный крестовый поход, уверяю вас.
Проверяя, работает ли регулярное выражение, я также попробовал его в php cli. Вот вывод:
Interactive shell
php > $str = 'abc<span class="blue"></span>def';
php > $pattern = "/<(title|h1|h2|h3|h4|h5|ul|ol|p|figure|caption|span)(.*?)><\/(\1)>/";
php > $final = preg_replace($pattern, '', $str);
php > print $final;
abc<span class="blue"></span>def
$str = 'abc<span class="blue"></span>def';
$pattern = "/<(title|h1|h2|h3|h4|h5|ul|ol|p|figure|caption|span)(.*?)><\/(\\1)>/";
// added \ ^
$final = preg_replace($pattern, '', $str);
print $final;
// echos 'abcdef'
объяснение:
"\1" // <-- character in octal notation
сильно отличается от
'\1' // <-- backslash and 1
потому что первая — это escape-последовательность. это также причина, по которой я почти исключительно использую строки в одинарных кавычках. увидеть http://php.net/string#language.types.string.syntax.double
Других решений пока нет …