Php 要查找父级的正则表达式::

Php 要查找父级的正则表达式::,php,regex,preg-match,Php,Regex,Preg Match,我要查找父项::、被调用函数和参数的所有匹配项 例如: parent::test( new ReflectionClass($this) ); 但以下正则表达式与外括号不匹配-仅与内括号匹配: parent::(.*)\((.*)\); Array /* output */ ( [0] => parent::test( new ReflectionClass($this) ); [1] => test( new ReflectionClass [2] =&g

我要查找父项::、被调用函数和参数的所有匹配项

例如:

parent::test( new ReflectionClass($this) );
但以下正则表达式与外括号不匹配-仅与内括号匹配:

parent::(.*)\((.*)\);
Array /* output */
(
    [0] => parent::test( new ReflectionClass($this) );
    [1] => test( new ReflectionClass
    [2] => $this) 
)
我必须如何修改模式


这是一个PHP脚本,所以我也可以使用一些其他字符串函数。

正则表达式通常不可能实现您所尝试的操作。要想做你想做的事情,你必须能够数数东西,这是正则表达式所不能做的

使匹配贪婪最终会导致匹配过多,特别是当您支持多行输入时

要替换父::的每一次出现,您可能不必精确匹配方法调用,也许匹配如下内容就足够了:

parent::(.*);

然后,您可以用其他内容替换parent::并使用第一个匹配组将文档中的内容放在这个位置。

正则表达式通常不可能执行此操作。要想做你想做的事情,你必须能够数数东西,这是正则表达式所不能做的

使匹配贪婪最终会导致匹配过多,特别是当您支持多行输入时

要替换父::的每一次出现,您可能不必精确匹配方法调用,也许匹配如下内容就足够了:

parent::(.*);

然后,您可以用其他内容替换parent::并使用第一个匹配组将文档中的内容放在这个位置。

下面是一个不太可靠的示例,但它与您问题中的情况相匹配

(parent::)([^\(]*)\(([^\(]*)\(([^()]*)\)
下面是一个实时的regex测试:(注意:rubular.com是针对ruby的,但对于php来说应该足够类似)

在这种情况下,匹配的元素将是:

parent::
test
new ReflectionClass
$this
如果您想要更健壮的东西,您可能需要研究解析工具(例如,编写一个与php函数定义相匹配的简短语法)或静态代码分析工具,因为这些工具通常由AST生成器等组成。我个人没有这方面的经验,但听起来相当全面:

pfff是一组工具和API,用于执行一些静态分析、动态 分析、代码可视化、代码导航或样式保持 源代码到源代码的转换,例如源代码重构。 目前的工作重点是PHP


这是一个不太可靠的示例,但它与您问题中的情况相匹配

(parent::)([^\(]*)\(([^\(]*)\(([^()]*)\)
下面是一个实时的regex测试:(注意:rubular.com是针对ruby的,但对于php来说应该足够类似)

在这种情况下,匹配的元素将是:

parent::
test
new ReflectionClass
$this
如果您想要更健壮的东西,您可能需要研究解析工具(例如,编写一个与php函数定义相匹配的简短语法)或静态代码分析工具,因为这些工具通常由AST生成器等组成。我个人没有这方面的经验,但听起来相当全面:

pfff是一组工具和API,用于执行一些静态分析、动态 分析、代码可视化、代码导航或样式保持 源代码到源代码的转换,例如源代码重构。 目前的工作重点是PHP


使用正则表达式解析代码是一个非常糟糕的主意。看一看,您可以使用它将PHP代码解析为令牌数组。您可以使用该数组来查找所需的信息

您还可以查看如何从这些令牌获取有意义的信息的示例

基本上,您需要找到T_PARENT instances T_STRING instances,字符串内容为'PARENT',后跟T_DOUBLE_冒号,后跟另一个包含方法名称的T_字符串,然后继续并开始计算括号的深度-无论何时到达'(“,将计数器增加1。每当到达“)”时,将计数器减少1。保留在过程中找到的所有内容的记录,直到计数器返回到0

类似的方法应该有效(未实际测试):


使用正则表达式解析代码是一个非常糟糕的主意。请看一看,您可以使用它将PHP代码解析为令牌数组。您可以使用该数组来查找所需的信息

您还可以查看如何从这些令牌获取有意义的信息的示例

基本上,您需要找到T_PARENT instances T_STRING instances,字符串内容为'PARENT',后跟T_DOUBLE_冒号,后跟另一个包含方法名称的T_字符串,然后继续并开始计算括号的深度-无论何时到达'(“,将计数器增加1。每当到达“)”时,将计数器减少1。保留在过程中找到的所有内容的记录,直到计数器返回到0

类似的方法应该有效(未实际测试):


如果您只对函数和圆括号内的内容感兴趣,
大多数父::调用只在一行中。这可能适合您

parent::(.*?)\((.*)\);
第一次捕获应在遇到
后停止,因为这不是贪婪。
第二次捕获不会停止,直到它捕获同一行上的最后一次
);


注意:不要使用
s
修饰符,因为这将导致贪婪匹配到最后一行
);
在多行代码中。

如果您只对函数和圆括号内的内容感兴趣,
大多数父::调用只在一行中。这可能适合您

parent::(.*?)\((.*)\);
第一次捕获应在遇到
后停止,因为这不是贪婪。
第二次捕获不会停止,直到它捕获同一行上的最后一次
);

注意:不要使用
s