【问题标题】:Regular expression to find and replace the content of HTML Comment Tags正则表达式查找和替换 HTML 注释标签的内容
【发布时间】:2010-10-01 06:46:08
【问题描述】:

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

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

我使用这个代码:

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

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

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

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

【问题讨论】:

  • 我猜你想在“si”之后添加一个“g”来进行全局搜索?

标签: php html regex non-greedy


【解决方案1】:

您可能希望正则表达式修饰符 U(PCRE_UNGREEDY,不贪婪地匹配)。这将获取最短的匹配,这意味着您不会从第一个

一个简短的例子:

<?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】:

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

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

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

【讨论】:

    【解决方案3】:
    $find_players = preg_match("/<!--PLAYER\=(.*?)-->/i", $html_content, $match);
    

    (.*?)

    应该可以正常工作。

    【讨论】:

    • 这里不需要'm'(多行)标志;它改变了未使用的 ^ 和 $ 元字符的含义。 's' 标志允许点匹配行分隔符。
    • s 和 m 修饰符在这里不需要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 2013-08-22
    • 1970-01-01
    • 2011-03-17
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多