正则表达式查找和替换HTML注释标签的内容

时间:2009-01-14 00:05:48

标签: php html regex non-greedy

我有一个CMS,它使用基于HTML注释的语法,让用户插入Flash视频播放器,幻灯片和其他用户无法轻易编写的“硬”代码。

一部FLV电影的语法如下所示: <!--PLAYER=filename.flv-->

我使用此代码:

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

如果只有一个播放器,$ match [1]包含文件名(这就是我需要的),这个效果很好

我对正则表达式的了解正在逐渐消失,所以我无法调整它以获得多个匹配。

如果页面上有更多内容,则会完全中断,因为它过于贪婪(从第一个<!--PLAYER到最后一个-->

3 个答案:

答案 0 :(得分:2)

您可能需要正则表达式修饰符U(PCRE_UNGREEDY,以便不匹配)。这将获取尽可能短的匹配,这意味着您将不会从第一个&lt;! - PLAYER =的开头到最后一个的结尾匹配 - &gt;

一个简短的例子:

<?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);

答案 1 :(得分:2)

使用正则表达式时,使用更具体的表达式而不是“懒惰点”通常会更高效,这通常会导致过多的回溯。您可以使用负向前瞻来获得相同的结果,而不会使正则表达式引擎负担过重:

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

请注意,使用惰性点不太可能会导致像这样的简单案例出现明显问题,但总是告诉正则表达式引擎完全你的意思是一个好习惯。在这种情况下,您希望在不传递注释终止符的情况下收集尽可能多的字符(“贪婪”)。终结符是破折号,后跟另一个破折号和大于号。因此,我们允许任何数量的任何字符破折号或破折号启动评论终止符。

答案 2 :(得分:1)

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

(。的 *吗

应该可以正常工作。