特殊文字を処理できません。
次のPerlスクリプトがあります。
while(@mapping_array[$i])
{
chomp(@mapping_array[$i]);
my @core= split ( / / , $mapping_array[$i]) ;
@core[0] =~ tr/ //ds ; ## Deleting blank spaces
@core[1] =~ tr/ //ds ;
system("perl -pi -e 's/@core[0]/@core[1]/' $testproc ");
print "@core[0] \n";
print "@core[1] \n";
$i++;
}
問題は、私の@core[0]
変数が単純な文字列(たとえば)でも、abc
より複雑な文字列(たとえば)でもよいことですTEST[1]
。私のスクリプトは期待どおりに動作し、そのabc
値を値に置き換えますが、私のスクリプトが失敗すると@core[1]
スクリプトは失敗します。@core[0]
TEST[1]
代わりに代替演算子を使用すると役に立ち?
ません。/
どうすれば正しくできますか?
答え1
あなたが探しているようですquotemeta
。説明したようにperldoc -f quotemeta
:
quotemeta EXPR
Returns the value of EXPR with all the ASCII non-"word" characters
backslashed. (That is, all ASCII characters not matching
"/[A-Za-z_0-9]/" will be preceded by a backslash in the returned
string, regardless of any locale settings.) This is the internal
function implementing the "\Q" escape in double-quoted strings.
したがって、スクリプトは次のようになります(配列要素は$foo[N]
nonで指定する必要があります@foo[N]
)。
chomp(@mapping_array);
while($mapping_array[$i])
{
my @core= split ( / / , $mapping_array[$i]) ;
$core[0] =~ tr/ //ds ; ## // Deleting blank spaces
$core[1] =~ tr/ //ds ; # / fix SO highlighting
my($k,$l)=(quotemeta($core[0]),quotemeta($core[1]))
system("perl -pi -e 's/$k/$l/' $testproc ");
print "$core[0] \n$core[1] \n";
$i++;
}
答え2
PerlでPerlを実行することは通常避けられます。
for my $both (@mapping) {
my ($regex, $replace) = split / /, $both;
tr/ //ds for $regex, $replace; # // Fix SO highlighting bug.
open my $IN, '<', $testproc or die $!;
open my $OUT, '>', "$testproc.new" or die $!;
while (<$IN>) {
s/\Q$regex/$replace/;
print {$OUT} $_;
}
close $OUT or die $!;
rename $testproc, "$testproc.old" or die $!;
rename "$testproc.new", $testproc or die $!;
}
\Q は次のようになります。参照要素これにより、$ regex変数の特殊文字は解釈されません。
答え3
最初 - プログラムの上部でstrict
開く:warnings
use strict;
use warnings;
@core[0]
これは実際に誤ったエラーなどのエラーを識別するのに役立ちます。
しかし、2番目の問題は正規表現にメタ文字を送信することです。これは[]
正規表現に特別なものがあることを意味します。
だから本当に必要なのはquotemeta
機能性です。
print quotemeta '@core[0]';
これは次のように変わります。
\@core\[0\]
または
print quotemeta $core[0];
提供された例では、次のように印刷されます。
TEST\[1\]
もちろん、system()
内部でも呼び出す必要はありません。それは非効率的で混乱しているだけです。 perl
perl
答え4
\Q
文字の特別な意味を削除するには、正規表現で使用してください。
system("perl -pi -e 's/\\Q$core[0]/$core[1]/' $testproc ");