2009-01-14 144 views
2

我有一个CMS,它使用基于HTML注释的语法来让用户插入用户无法轻松插入的Flash视频播放器,幻灯片和其他“硬”代码写。正则表达式来查找和替换HTML注释标签的内容

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

我用这个代码:

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

这个伟大的工程,如果只有一个球员,$匹配[1]包含文件名(这是我需要的)

我对正则表达式的认识正在消失,所以我无法调整这个来获取多个匹配。

如果有更多的页面,它打破完全,因为它匹配太贪婪地(从第一<!--PLAYER到最后-->

+0

我想你想在“si”之后加一个“g”来做全局搜索吗? – some 2009-01-14 00:11:11

回答

2

你可能需要一个正则表达式修饰符U(PCRE_UNGREEDY,不合适地匹配)。这会获得尽可能短的匹配,这意味着你不会从开头匹配o f头< - 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); 
1
$find_players = preg_match("/<!--PLAYER\=(.*?)-->/i", $html_content, $match); 

*?

应该工作很好,

+0

这里不需要'm'(多行)标志;它改变了未被使用的^和$元字符的含义。这是允许点匹配行分隔符的's'标志。 – 2009-01-14 02:05:15

+0

这里不需要s和m修饰符。 – OIS 2009-01-14 03:31:08

2

当使用正则表达式,它通常更高性能的使用的更具体的表达,而不是“懒点”,这通常会导致过度的回溯。您可以使用负前瞻,以达到同样的效果,而不负担过重的正则表达式引擎:

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

你要知道,这是不可能的使用懒点会造成明显的问题,一个简单的情况就是这样,但它是一个好习惯总是告诉正则引擎究竟是你的意思。在这种情况下,您希望收集尽可能多的字符(“贪婪”)而不传递注释终止符。终止符是一个破折号,后面是另一个破折号和一个大于号的符号。所以,我们允许任何数量的任何字符除了破折号或破折号不要开始注释终止符。