Perl 如何使用';s//';如果我的字符串包含一个'/';?
我在Mac10.6.6上使用Perl5.10.6。我想对一个文件执行一个简单的搜索和替换,因此我尝试:Perl 如何使用';s//';如果我的字符串包含一个'/';?,perl,Perl,我在Mac10.6.6上使用Perl5.10.6。我想对一个文件执行一个简单的搜索和替换,因此我尝试: my $searchAndReplaceCmd = "perl -pi -e 's/\\Q${localTestDir}\\E//g' ${testSuiteFile}"; system( $searchAndReplaceCmd ); 但是上面的问题是变量$localTestDir包含目录分隔符(“/”),这会破坏正则表达式 在操作员期望的-e线1附近找到Bareword “s/\Q/ho
my $searchAndReplaceCmd = "perl -pi -e 's/\\Q${localTestDir}\\E//g' ${testSuiteFile}";
system( $searchAndReplaceCmd );
但是上面的问题是变量$localTestDir
包含目录分隔符(“/”
),这会破坏正则表达式
在操作员期望的-e线1附近找到Bareword
“s/\Q/home/selenium”
在运算符应位于-e的位置找到反斜杠
第1行,靠近“Live\”的语法错误位于-e第1行,靠近
“s/\Q/home/selenium”
搜索模式未终止于-e第1行
当所讨论的变量包含正则表达式字符时,如何对文件执行搜索和替换?谢谢 似乎
$localTestDir
以/
开头
通过将regex分隔符更改为/
以外的内容进行补救:
my $searchAndReplaceCmd = "perl -pi -e 's!\\Q${localTestDir}\\E!!g' ${testSuiteFile}";
发件人: 最后一个示例显示
s//
可以使用其他分隔符,例如
s
和s{}{}
,甚至s{}/
。如果使用单引号s'
,则
regex和replacement被视为单引号字符串
更改分隔符很有用,但更一般地说,您可以在任何正则表达式字符前面加上反斜杠,使其成为非特殊字符
因此,s/\/abc/\/xyz/将起作用,尽管它的可读性不是很好。问题是,为什么要在perl中,通过shell,在perl中进行搜索和替换。这似乎是一种迂回的处理方式,您将遇到shell插值的问题
\Q\E
应该覆盖字符串中的特殊字符,因此/
不应该是一个问题。发件人:
这里有一个替代方案(未经测试),全部是perl解决方案。如果您想更加确定,请将/
分隔符交换为其他内容,例如s###
(您可以使用任何字符作为分隔符)
问题是,
$localTestDir
的替换太快了
这里有一种方法可以让您对重新分隔符使用/
:
system('perl', '-pi',
'-e', 'BEGIN { $dir = shift(@ARGV) };',
'-e', 's/\\Q$dir\\E//g',
$localTestDir,
$suiteTestFile
);
请注意,这还可以保护
$suiteTestFile
的内容不被shell解释。又名“倾斜牙签综合症”:)@Dave Perl非常可爱;)系统调用可能很方便,但几乎总是最好使用纯perl IMO。但是如果$localTestDir
包含,该怎么办呢
?@user5402:看看perlrequick
中的示例,使用另一个分隔符:s####
,s,,,,
,s
,s{}/
,等等。我的观点是,在知道$localTestDir
是什么之前,必须选择一个分隔符。如果$localTestDir
包含所有ASCII字符怎么办?现在你该怎么办?@user5402:放一个反斜杠,当然,在中还有quotemeta
选项
\Q quote (disable) pattern metacharacters till \E
use strict;
use warnings;
use File::Copy;
open my $fh, '<', $testSuiteFile or die $!;
open my $out, '>', $testSuiteFile . ".bak" or die $!;
while (<$fh>) {
s/\Q${localTestDir}\E//g;
print $out $_;
}
move($testSuiteFile . ".bak", $testSuiteFile) or die $!;
use strict;
use warnings;
use Tie::File;
tie, my @file, 'Tie::File', $testSuiteFile or die $!;
for (@file) {
s/\Q${localTestDir}\E//g;
}
untie @file;
system('perl', '-pi',
'-e', 'BEGIN { $dir = shift(@ARGV) };',
'-e', 's/\\Q$dir\\E//g',
$localTestDir,
$suiteTestFile
);