2

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

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

我使用这段代码:

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

如果只有一个玩家,这很好用, $match[1] 包含文件名(这就是我所需要的)

我对正则表达式的了解正在消失,因此我无法对其进行调整以获取多个匹配项。

如果页面上还有更多,它会完全中断,因为它太贪婪地匹配(从第一个<!--PLAYER到最后一个-->

4

3 回答 3

2

您可能希望正则表达式修饰符 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);
于 2009-01-14T00:16:01.737 回答
2

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

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

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

于 2009-01-14T00:33:11.423 回答
1
$find_players = preg_match("/<!--PLAYER\=(.*?)-->/i", $html_content, $match);

(. *? )

应该可以正常工作。

于 2009-01-14T00:11:26.507 回答