假设我们有一个名为项目。我想&$
在函数调用时找到文件夹中包含模式的每个文件。
例如应该替换:
AnyFunction(&$arg);
和
AnyFunction($arg);
AnyFunction
与模式匹配的未知函数在哪里。
我需要这个来尝试解决这个问题php问题。
如果可能的话我也想,如果一个函数与模式匹配,它的声明也会改变:
function AnyFunction(&$arg)
我该如何执行此操作?
答案1
如果您的源代码格式合理,则可以采用简单的文本方法,除非前面有单词,否则将起作用:AnyFunction(arg1, &$arg2)
与函数调用在同一行上没有函数声明,函数名称之间没有注释或换行符,没有包含不平衡的注释函数调用内的括号等。这将捕获注释和字符串文字,并且可能会错过一些复杂的函数调用(例如,它不会捕获in )。AnyFunction(arg1, $arg2)
function
function
&$arg2
f(g(), &$arg2)
在您的文件上运行此脚本,它们将被就地修改。警告:未经测试,请先备份!
#!/usr/bin/perl -pi
BEGIN { use warnings; use strict; undef $/; }
sub straighten_ampersands {
my ($args, $want_ampersands) = @_;
$want_ampersands = ($want_ampersands ? "&" : "");
$args =~ s{ ([(,]\s*) &? (\$\w) }
{ $1 $want_ampersands $2 }x;
}
s{
(\bfunction\s+|)(\w+\s+) # optional 'function' keyword, then function name
(\((?:(?>[^()]+)|(?4))*)\))) # balanced parentheses (from perlre)
}{
"$1$2" . straighten_ampersands($3, $1 ne "")
}ex
答案2
这是相当直接的搜索并用 sed 替换。
最简单的情况,如果您可以相当确定没有任何其他实例
&$
您不想更改:find Project -name '*.php' -print0 | xargs -0r sed -i -e 's/&\$/$/g'
如上所述,但将搜索和替换限制为函数调用或定义的第一个参数(如上面的示例所示):
find Project -name '*.php' -print0 | xargs -0r sed -i -e 's/(&\$/($/g'
与上面的 1. 相同,但将替换限制为括号内出现 &$ 的行:
find Project -name '*.php' -print0 | xargs -0r sed -i -e '/([^)]*&\$[^)]*)/ s/&\$/$/g'
注意1:这仍然会改变
&$
同一行上括号外的任何其他内容,但仅限于已经在括号内找到的行(...&$...)
注意2:这不会
&$
在多行函数调用或定义的第二行和后续行上改变......它们与搜索条件不匹配。
在所有情况下,请制作项目目录的工作副本并使用它。当它更改为您想要的内容并且您已经测试它是否有效(至少不会引入比它解决的问题更多的问题)时,将真实的项目目录移到一边(例如mv Project Project.old
),然后将修改后的项目移动到位(例如 mv Project.workingcopy Project
)