从代码文件中提取PHP函数的PHP正则表达式

从代码文件中提取PHP函数的PHP正则表达式,php,regex,function,static-analysis,Php,Regex,Function,Static Analysis,我试图制作一个PHP正则表达式,从PHP源代码中提取函数。到目前为止,我使用递归正则表达式来提取{}之间的所有内容,但它也匹配if语句之类的内容。当我使用类似于: preg_match_all("/(function .*\(.*\))({([^{}]+|(?R))*})/", $data, $matches); 当文件中有多个函数时,它不起作用(可能是因为它也使用了递归中的“函数”部分) 有没有办法做到这一点 示例文件: <?php if($useless) { echo "i d

我试图制作一个PHP正则表达式,从PHP源代码中提取函数。到目前为止,我使用递归正则表达式来提取{}之间的所有内容,但它也匹配if语句之类的内容。当我使用类似于:

preg_match_all("/(function .*\(.*\))({([^{}]+|(?R))*})/", $data, $matches);
当文件中有多个函数时,它不起作用(可能是因为它也使用了递归中的“函数”部分)

有没有办法做到这一点

示例文件:

<?php
if($useless)
{
  echo "i don't want this";
}

function bla($wut)
{
  echo "i do want this";
}
?>

regexps是一种错误的方法。考虑或

< P>从重复问题中移动:

正则表达式解决方案:

$regex = '~
  function                 #function keyword
  \s+                      #any number of whitespaces 
  (?P<function_name>.*?)   #function name itself
  \s*                      #optional white spaces
  (?P<parameters>\(.*?\))  #function parameters
  \s*                      #optional white spaces
  (?P<body>\{.*?\})        #body of a function
~six';

if (preg_match_all($regex, $input, $matches)) {
  print_r($matches);
}
$regex='1!'~
函数#函数关键字
\s+#任意数量的空格
(?P.*)#函数名本身
\s*#可选空格
(?P\(.*)函数参数
\s*#可选空格
(?P\{.*})函数体
~6';
if(preg_match_all($regex,$input,$matches)){
打印(匹配项);
}
附言。 正如上面所建议的,标记器是更好的方法。

Regex接受正文中的递归花括号

我知道有一个选择的答案,但如果不能使用标记器,这是一个从php代码中提取函数(名称、参数和主体)的简单正则表达式

与上面Ioseb答案的主要区别在于,这个正则表达式接受主体中带有递归花括号的情况,这意味着它不会在第一个花括号关闭后停止

/function\s+(?<name>\w+)\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/

考虑这一点:<代码> $s=“FO函数”(bar);
/*no function()*/
并考虑这样一个事实,像
/*
这样的东西也可以放在字符串文本中(反之亦然)。简言之:不要使用正则表达式(参见stereofrog的答案)。作为正则表达式的替代方法(正则表达式永远无法正确处理所有边缘情况),此答案解释了如何使用PHP编写的PHP解析器从一段代码中提取函数:
/                                   # delimiter
function                            # function keyword
\s+                                 # at least one whitespace
(?<name>\w+)                        # function name (a word) => group "name"
\s*                                 # optional whitespace(s)
\((?<param>[^\)]*)\)                # function parameters => group "param"
\s*                                 # optional whitespace(s)
(?<body>\{(?:[^{}]+|(?&body))*\})   # body function (recursive curly brackets allowed)  => group "body"
/                                   # delimiter
$data = '
    <?php 
    function my_function($param){
        if($param === true){
            // This is true
        }else if($param === false){
            // This is false
        }else{
            // This is not
        }
    }
    ?>
';

preg_match_all("/function\s+(?<name>\w+)\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/", $data, $matches);
print_r($matches['body']);

/*
Array
(
    [0] => {
        if($param === true){
            // This is true
        }else if($param === false){
            // This is false
        }else{
            // This is not
        }
    }
)
*/
function my_function(){
    echo "A curly bracket : }";
    echo "Another curly bracket : {";
}

/*
Array
(
    [0] => {
    echo "A curly bracket : }
)
*/