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生成器等组成。我个人没有这方面的经验,但听起来相当全面:
这是一个不太可靠的示例,但它与您问题中的情况相匹配
(parent::)([^\(]*)\(([^\(]*)\(([^()]*)\)
下面是一个实时的regex测试:(注意:rubular.com是针对ruby的,但对于php来说应该足够类似)
在这种情况下,匹配的元素将是:
parent::
test
new ReflectionClass
$this
如果您想要更健壮的东西,您可能需要研究解析工具(例如,编写一个与php函数定义相匹配的简短语法)或静态代码分析工具,因为这些工具通常由AST生成器等组成。我个人没有这方面的经验,但听起来相当全面:
使用正则表达式解析代码是一个非常糟糕的主意。看一看,您可以使用它将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