Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex $&;未作为perl替换的一部分进行解析_Regex_Perl - Fatal编程技术网

Regex $&;未作为perl替换的一部分进行解析

Regex $&;未作为perl替换的一部分进行解析,regex,perl,Regex,Perl,我有一个perl脚本,可以搜索和替换多个文件中的数据。由于一个文件中可以替换多个单词,因此我编写了一个函数,该函数将搜索和替换模式作为数组接受。然后在这个函数中循环数组并执行替换。它工作得很好,但仅对于一个特定的文件,我需要在匹配的字符串(字符#)前面追加一些内容。因此,我将“\$&”作为替换模式传递。它被正确地接收,但不知何故,$从未被解析。相反,该操作将用文本值“#$&”替换匹配的字符串。如果我在readFile函数的替换命令中直接使用#$&也可以实现同样的效果。我知道我们可以通过其他方式实

我有一个perl脚本,可以搜索和替换多个文件中的数据。由于一个文件中可以替换多个单词,因此我编写了一个函数,该函数将搜索和替换模式作为数组接受。然后在这个函数中循环数组并执行替换。它工作得很好,但仅对于一个特定的文件,我需要在匹配的字符串(字符#)前面追加一些内容。因此,我将“\$&”作为替换模式传递。它被正确地接收,但不知何故,$从未被解析。相反,该操作将用文本值“#$&”替换匹配的字符串。如果我在readFile函数的替换命令中直接使用#$&也可以实现同样的效果。我知道我们可以通过其他方式实现这个结果,但我真的想知道为什么相同的替换模式在直接传递时有效,而在作为数组元素读取时无效。 我已经对工作良好的替换命令进行了注释,以供参考。有人能帮我找出这个问题吗

my @search= ("host\\s*(replication|all)");
my @replace= ("#\$&");

my $sLine = scalar @search;
my $rLine = scalar @replace;

my $data = ???;

for ( my $i=0; $i < $sLine; $i++)
{
     print("\n search = $search[$i]  replace = $replace[$i] \n");
     #$data =~ s/$search[$i]/#$&/g; ==> this works
     $data =~ s/$search[$i]/$replace[$i]/g; #==> this doesn't
}

print($data);
my@search=(“主机\\s*(复制|全部)”);
my@replace=(“\$&”);
my$sLine=scalar@search;
my$rLine=scalar@replace;
我的$data=???;
对于(我的$i=0;$i<$sLine;$i++)
{
打印(“\n search=$search[$i]replace=$replace[$i]\n”);
#$data=~s/$search[$i]/#$&/g;=>
$data=~s/$search[$i]/$replace[$i]/g;#==>这不正确
}
打印(数据);

工作溶液和非工作溶液之间的差异与

print "#$&";              # Prints `#` and the value of `$&`.

您可以使用以下选项:

use String::Substitution qw( gsub_modify );

for my $i (0..$#search) {
   gsub_modify($data, $search[$i], $replace[$i]);
}

这是一个更深入的解释

s/$search[$i]/#$&/g
是的缩写

s/$search[$i]/  "#$&"   /eg
s/$search[$i]/  "$replace[$i]"   /eg
这相当于

s/$search[$i]/  "#" . $&   /eg    # Replaces with `#` and the value of `$&`.
s/$search[$i]/  $replace[$i]   /eg    # Replaces with the value of `$replace[$i]`.
/e
使替换表达式作为Perl代码计算,并将其结果用作替换字符串

另一方面,

s/$search[$i]/$replace[$i]/g
是的缩写

s/$search[$i]/  "#$&"   /eg
s/$search[$i]/  "$replace[$i]"   /eg
这相当于

s/$search[$i]/  "#" . $&   /eg    # Replaces with `#` and the value of `$&`.
s/$search[$i]/  $replace[$i]   /eg    # Replaces with the value of `$replace[$i]`.

您正在用
$replace[$i]
中保存的字符串替换匹配的字符串。该字符串本身不会被计算。在旧(低于5.020)解释器版本中使用$会导致全局性能损失。请阅读perldocperlfaq6和perldocperlvar。@Dada,与您所说的相反,您的解决方案在很大程度上取决于代码注入。例如,尝试使用
my@search='.*';我的@replace=”.print(“owned\n”)。“;$\u=”(当然,这是恶意代码注入,但如果replace表达式中包含
,即使不是恶意的,代码也会失败。)是的,是的,但我的意思是,有了他的替代,没有什么好担心的。我最初写了一段警告这些漏洞,但由于他的例子是安全的,我反对它。然而,我意识到,有这样的建议使用/ee的答案不是一件好事,因为不太了解的人可能会在不谨慎的情况下使用它h、 这就是为什么我删除了我的答案。Thx for you comments;我认为你不建议使用/ee;)@Dada是正确的,如果你真的相信替换表达式是固定的,你会建议
s/$search[$I]/#$&/g
显然没有固定,但它不一定是
。.exec(“cat/etc/passwd&&rm-rf/”。
。。。看起来更像是出现在某处的带有
$&
的常规字符串…@Dada,没有,但可能是。或者它甚至可以是像
“$&”
或者甚至
a“b”c
这样简单的东西。由于解决方案中的代码注入错误,所有这些都将失败。