Регулярное выражение для поиска и замены содержимого тегов комментариев HTML. - PullRequest
2 голосов
/ 14 января 2009

У меня есть CMS, которая использует синтаксис, основанный на комментариях HTML, чтобы позволить пользователю вставлять флэш-видео плееры, слайд-шоу и другой «жесткий» код, который пользователь не мог легко написать.

Синтаксис для одного FLV-фильма выглядит следующим образом: <!--PLAYER=filename.flv-->

Я использую этот код:

$find_players = preg_match("/<!--PLAYER\=(.*)-->/si", $html_content, $match);

Это прекрасно работает, если есть только один игрок, $ match [1] содержит имя файла (это все, что мне нужно)

Мои знания о регулярных выражениях исчезают, поэтому я не могу настроить это, чтобы получить более одного совпадения.

Если на странице есть еще что-то, она полностью ломается, потому что слишком жадно совпадает (с первого <!--PLAYER до последнего -->

Ответы [ 3 ]

2 голосов
/ 14 января 2009

Вы, вероятно, хотите, чтобы модификатор regex U (PCRE_UNGREEDY, не совпадал). Это приведет к наименьшему возможному совпадению, что означает, что вы не будете совпадать с начала первого <! - PLAYER = до конца последнего ->

Сокращенный пример:

<?php
$text = "blah\n<!-x=abc->blah<!-x=def->blah\n\nblah<!-x=ghi->\nblahblah" ;
$reg  = "/<!-x=(.*)->/U" ;
preg_match_all( $reg, $text, $matches ) ;
print_r( $matches ) ;

Ваш код становится:

$find_players = preg_match_all("/<!--PLAYER=(.*)-->/Ui", $html_content, $matches);
// print $matches[1] ;

Модификатор 's' (PCRE_DOTALL), который вы используете, вероятно, также бесполезен; вряд ли у вас будет имя файла с переводом строки.

РЕДАКТИРОВАТЬ: @Stevens предлагает этот синтаксис, который я согласен, немного яснее - перемещение модификатора U в скобки захвата.

$find_players = preg_match_all("/<!--PLAYER=(?U)(.*)-->/i", $html_content, $matches);
2 голосов
/ 14 января 2009

При работе с регулярными выражениями обычно более целесообразно использовать более конкретное выражение, а не «ленивую точку», что обычно вызывает чрезмерный возврат. Вы можете использовать отрицательный прогноз для достижения тех же результатов, не перегружая движок регулярных выражений:

$find_players = preg_match("/<!--PLAYER=((?:[^-]+|-(?!->))*)-->/ig", $html_content, $match);

Имейте в виду, что маловероятно, что использование ленивой точки вызовет заметные проблемы в простом случае, подобном этому, но это хорошая привычка всегда указывать механизму регулярных выражений точно , что вы имеете в виду. В этом случае вы хотите собрать как можно больше символов («жадных»), не передавая терминатор комментария. Терминатор - это тире, за которым следует еще один тире и знак «больше». Таким образом, мы допускаем любое число любого символа , кроме тире или тире, которые не запускают терминатор комментария.

1 голос
/ 14 января 2009
$find_players = preg_match("/<!--PLAYER\=(.*?)-->/i", $html_content, $match);

(. * )

должно работать просто отлично.

...