非贪婪的正则表达式

时间:2013-03-01 03:48:19

标签: php regex regex-greedy non-greedy

我需要在注释php文件中的某些标记内获取值,如此

php code
/* this is a comment
!-
<titulo>titulo3</titulo>
<funcion>
   <descripcion>esta es la descripcion de la funcion 6</descripcion>
</funcion>
<funcion>
   <descripcion>esta es la descripcion de la funcion 7</descripcion>
</funcion>
<otros>
   <descripcion>comentario de otros 2a hoja</descripcion>
</otros>
-!
*/
some php code

因此你可以看到文件有换行符和<funcion></funcion>等标签的重复,我需要获得每一个标签,所以我尝试这样的事情:

preg_match_all("/(<funcion>)(.*)(<\/funcion>)/s",$file,$matches);

这个例子适用于新行,但它贪婪,所以我一直在寻找和看到这两个解决方案:

preg_match_all("/(<funcion>)(.*?)(<\/funcion>)/s",$file,$matches);
preg_match_all("/(<funcion>)(.*)(<\/funcion>)/sU",$file,$matches);

但它们都不适合我,不知道为什么

4 个答案:

答案 0 :(得分:1)

试试这个..

 /<funcion>((.|\n)*?)<\/funcion>/i

<强>例如

$srting = "<titulo>titulo3</titulo>
<funcion>
   <descripcion>esta es la descripcion de la funcion 6</descripcion>
</funcion>
<funcion>
   <descripcion>esta es la descripcion de la funcion 7</descripcion>
</funcion>
<otros>
   <descripcion>comentario de otros 2a hoja</descripcion>
</otros>";

$result=preg_match_all('/<funcion>((.|\n)*?)<\/funcion>/i', $srting,$m);
print_r($m[0]);

此输出

Array
(
    [0] => 
   esta es la descripcion de la funcion 6

    [1] => 
   esta es la descripcion de la funcion 7

)

<强> DEMO

答案 1 :(得分:1)

您的问题中的这个表达式:

preg_match_all("/(<funcion>)(.*?)(<\/funcion>)/s", $file, $matches);
print_r($matches);

这将有效,但只有$file是包含XML的字符串;如果它是文件名,则必须先获取内容:

preg_match_all("/(<funcion>)(.*?)(<\/funcion>)/s", file_get_contents($file), $matches);

另外,请记住,当您使用非贪婪模式时,PCRE有backtrack limitations

答案 2 :(得分:1)

。 。如果结构完全相同(总是在内容中缩进),您可以轻松地将其与 / \ n [\ s] +([^ \ n] +(\ n [\ s] +)*)\ n匹配/

。 。我总是倾向于避免使用“懒惰”(“非贪婪”)修饰符。它只是看起来像一个黑客,并没有到处都可用,并具有相同的实现。由于在这种情况下您似乎不需要,我建议您不要使用它。

。 。试试这个:

$regexp = '/<funcion>\n[\s]+([^\n]+(\n[\s]+)*)\n</funcion>/';
$works = preg_match_all($regexp, $file, $matches);
echo '<pre>';
print_r($matches);

。 。 “$ matches [1]”数组将为您提供“funcion”标签内容的数组。

。 。当然,预先过滤内容并在注释内容上应用RegExp以避免任何不匹配会很好。

。 。玩得开心。

答案 3 :(得分:0)

尝试使用[\s\S],这意味着所有空格和非空格字符,而不是.。此外,您无需在匹配组中添加<funcion></funcion>

/<funcion>([\s\S]*?)<\/funcion>/s

另外,请记住,执行此操作的最佳方法是使用XML parser解析XML。即使它不是XML文档,正如您在评论中提到的那样,提取应该解析的部分并使用XML解析器来解析它。