특수 문자를 처리할 수 없습니다.
다음 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]
아닌 으로 지정되어야 합니다 @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]
이는 실제로 잘못된 오류 와 같은 오류를 식별하는 데 도움이 됩니다 .
그러나 두 번째 문제는 정규식에 메타 문자를 보내는 것입니다. 이는 []
정규식에 특별한 것이 있음을 의미합니다.
그래서 정말로 필요한 것은 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 ");