括号内的正则表达式文本

时间:2014-01-21 21:31:58

标签: php regex nested

我有一个问题,我不知道如何解决这个问题,如果正则表达式是最好的方法。 我的想法是在文件中获取函数的名称,变量和内容。 这是我的正则表达式:

preg_match_all('/function (.*?)\((.*?)\)(.*?)\{(.*?)\}/s',$content,$funcs,PREG_SET_ORDER);  

我有这个测试文件:

function testfunc($text)
{

if ($text)
{
    return 1;
}
return 0;
}

当然我会在返回0之前获得所有内容直到“}”; 有没有办法让函数中的所有内容都找到正确的“}”。

4 个答案:

答案 0 :(得分:3)

与许多信念相反,PHP(PCRE)有一个名为Recursive Pattern Regex的东西,可以让你找到匹配的嵌套括号。请考虑以下代码:

$str = <<<'EOF'
function testfunc($text) {
   if ($text) {
       return 1;
   }
   return 0;
}
EOF;

if ( preg_match('/ \{ ( (?: [^{}]* | (?0) )+ ) \} /x', $str, $m) )
   echo $m[0];

输出:

{
   if ($text) {
       return 1;
   }
   return 0;
}

更新:要捕获函数名称和参数,请尝试以下代码:

$str = <<<'EOF'
function testfunc($text) {
   if ($text) {
       return 1;
   }
   return 0;
}
EOF;
if ( preg_match('/ (function [^{]+ ) ( \{ (?: [^{}]* | (?-1) )* \} ) /x', $str, $m) )
   print_r ($m);

输出

Array
(
    [0] => function testfunc($text) {
   if ($text) {
       return 1;
   }
   return 0;
}
    [1] => function testfunc($text) 
    [2] => {
   if ($text) {
       return 1;
   }
   return 0;
}
)

在线演示:http://ideone.com/duQw9c

答案 1 :(得分:1)

正则表达式不是该工作的最佳工具。解析器是。

毫无疑问,您可以使用正则表达式回调来最终管理您的意图,但这将是不合理的混淆和脆弱。

解析器可以轻松完成相同的工作。更好的是,如果您计划使用PHP解析PHP,您可以使用Zend解析器为您完成工作。

答案 2 :(得分:0)

一般情况下(你当然可以为两级深度解析定义一个类似function (.*)\((.*)\)(.*)\{([^}]*(\{[^}]*\})*)\}的正则表达式但是因为你可以任意深度嵌套这样的结构,你最终会用完正则表达式:D) 。人们需要一个无上下文语法才能做到这一点。

您可以使用Yacc,Bison,Gppg等生成此类语法分析器...

此外,您无需声明.*?.*表示零次或多次,.+表示一次或多次。

答案 3 :(得分:0)

  

有没有办法让函数中的所有内容都找到正确的“}”。

简答:不。

长答案: 单个表达式无法处理此问题。 {}也可能出现在方法正文中,因此很难找到正确的结尾}。您需要处理(迭代或递归)所有{}对并手动排序所有对,前面有“方法名称”。

但这也不简单,因为你需要排除所有语句,它们看起来像一个函数,但在方法体内是有效的。

我不认为,正则表达式是完成这项任务的方法。即使您设法创建所有必需的Regex-Pattern - 与任何专用解析器相比,性能会更差。