У меня есть CMS, которая использует синтаксис, основанный на комментариях HTML, чтобы пользователь мог вставлять flash-видеоплееры, слайд-шоу и другой «жесткий» код, который пользователю было бы нелегко написать.
Синтаксис одного фильма в формате FLV выглядит так:
<!--PLAYER=filename.flv-->
Я использую этот код:
$find_players = preg_match("/<!--PLAYER\=(.*)-->/si", $html_content, $match);
Это отлично работает, если есть только один игрок, $ match [1] содержит имя файла (это все, что мне нужно)
Мои знания о регулярных выражениях исчезают, поэтому я не могу настроить это, чтобы получить более одного совпадения.
Если на странице их больше, он полностью ломается, потому что он слишком жадно соответствует (от первого <!--PLAYER до последнего -->






$find_players = preg_match("/<!--PLAYER\=(.*?)-->/i", $html_content, $match);
(.*?)
должно работать нормально.
Флаг «m» (многострочный) здесь не нужен; он изменяет значение метасимволов ^ и $, которые не используются. Флаг 's' позволяет точке совпадать с разделителями строк.
Модификаторы s и m здесь не нужны.
Вероятно, вы хотите, чтобы модификатор регулярного выражения 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);
или просто /<!--PLAYER=(.*?)-->/. Знак вопроса после звездочки отменяет жадность.
При работе с регулярными выражениями, как правило, более производительно использовать более конкретное выражение, чем «ленивую точку», которая обычно вызывает чрезмерный поиск с возвратом. Вы можете использовать отрицательный просмотр вперед для достижения тех же результатов, не перегружая механизм регулярных выражений:
$find_players = preg_match("/<!--PLAYER=((?:[^-]+|-(?!->))*)-->/ig", $html_content, $match);
Имейте в виду, что использование ленивой точки вряд ли вызовет заметные проблемы в таком простом случае, как этот, но это хорошая привычка всегда сообщать механизму регулярных выражений точно, что вы имеете в виду. В этом случае вы хотите собрать как можно больше символов («жадных»), не передавая терминатор комментария. Терминатор - это тире, за которым следует тире и знак «больше». Таким образом, мы разрешаем любое количество символов Кроме или тире, которые не запускают терминатор комментария.
Я думаю, вы хотите добавить букву "g" после "si", чтобы выполнить глобальный поиск?