Php 查找包含所有参数的函数调用

Php 查找包含所有参数的函数调用,php,regex,Php,Regex,我需要搜索(并替换)php文件以创建对象,如: $this->Add(new MyObject("Hello", "World"), ...); 到目前为止,这一方法适用于: $pattern = '/new MyObject\((.*)\)/isU'; preg_replace_callback($pattern, function($hit) { // Replace },

我需要搜索(并替换)php文件以创建对象,如:

$this->Add(new MyObject("Hello", "World"), ...);
到目前为止,这一方法适用于:

$pattern = '/new MyObject\((.*)\)/isU';
    preg_replace_callback($pattern,
        function($hit)
        {   // Replace
        },
        $file);
我的问题是,参数可以包含括号,如:

$this->Add(MyObject("Hello (this is a bracket)", "World"), ...);
这使得模式仅检测调用的一部分:

new MyObject("Hello (this is a bracket)
而不是

MyObject("Hello (this is a bracket)", "World")
有没有办法修改模式,使其不会在单引号或双引号内的括号中起作用

我试过这样的方法:

$pattern = '/new MyObject\(".*?"(*SKIP)(*FAIL)|([^\)].*)\)/isU';

但这只会找到所有类型的对象,而不仅仅是所需的MyObject。

使用标志
/U
会使量词变懒,因此模式
新MyObject\(.*)
将被解释为
新MyObject\(.*?)
使结束
在第一次出现时停止

您可以做的是匹配
新的MyObject
,然后匹配循环第一个子例程的平衡括号

new MyObject(\((?>[^()]+|(?1))*\))
解释

  • 新建MyObject
    按字面匹配
  • Capturegroup 1
    • \(
      匹配
    • (?>[^()]+|(?1))*
      重复0多次匹配除
      之外的任何字符,或递归第一个捕获组
    • \)
      匹配
  • 关闭第1组

要在单引号或双引号中使用括号,请执行以下操作:

\b(?:new\h+)?MyObject(\((?>[^()"']+|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|(?1))*\))

啊,谢谢,到目前为止效果还不错!它假设每个开始括号(有一个对应的结束括号),对吗?我必须检查是否总是这样。@沃纳我明白你的意思,我添加了另一个模式,它将从开始到结束单引号或双引号匹配你的上一个正则表达式不匹配
$this->Add(MyObject(“你好(这是一个括号)”,“World”),…)。顺便说一句,这不可能为此类任务创建一个合适且可维护的正则表达式,它应该能够检测函数调用中所有可能的令牌类型。它可能被用来匹配某个特定的子集,或者需要做更多的工作才能使其工作。@WiktorStribiż当你认为你有这种感觉,而有人打破了你的模式时,你会发现这两个外观都是无用的。没有太大的不同,但我特别建议捕捉括号之间的内容。