Perl正規表現を使用して、特定の文字列内のいくつかの特殊文字をエスケープしようとしています。ドル記号を除くすべての文字で正常に機能します。私は以下を試しました:
my %special_characters;
$special_characters{"_"} = "\\_";
$special_characters{"$"} = "\\$";
$special_characters{"{"} = "\\{";
$special_characters{"}"} = "\\}";
$special_characters{"#"} = "\\#";
$special_characters{"%"} = "\\%";
$special_characters{"&"} = "\\&";
my $string = '$foobar';
foreach my $char (keys %special_characters) {
$string =~ s/$char/$special_characters{$char}/g;
}
print $string;
これを試して:
my %special_characters;
$special_characters{"_"} = "\\_";
$special_characters{"\\\$"} = "\\\$";
$special_characters{"{"} = "\\{";
$special_characters{"}"} = "\\}";
$special_characters{"#"} = "\\#";
$special_characters{"%"} = "\\%";
$special_characters{"&"} = "\\&";
奇妙に見えますか?正規表現は次のようにする必要があります。
s/\$/\$/g
正規表現の最初の部分では、「$」は文字列の終わりを示す特別な正規表現文字であるため、エスケープする必要があります。
正規表現の2番目の部分は「通常の」文字列と見なされます。「$」には特別な意味はありません。したがって、バックスラッシュは実際のバックスラッシュですが、最初の部分ではドル記号をエスケープするために使用されています。
さらに、変数の定義では、バックスラッシュとドル記号をエスケープする必要があります。これらは両方とも、二重引用符で囲まれた文字列で特別な意味を持つためです。
各文字をバックスラッシュが前に付いた文字で置き換える場合は、ハッシュは必要ありません。必要なものに一致させ、その前にバックスラッシュを置きます。
s/($re)/"\\$1"/eg;
すべての文字の正規表現を作成するには、 Regexp :: Assemble が最適です。
use v5.10.1;
use Regexp::Assemble;
my $ra = Regexp::Assemble->new;
my @specials = qw(_ $ { } # % & );
foreach my $char ( @specials ) {
$ra->add( "\\Q$char\\E" );
}
my $re = $ra->re;
say "Regex is $re";
while( <DATA> ) {
s/($re)/"\\$1"/eg;
print;
}
__DATA__
There are $100 dollars
Part #1234
Outside { inside } Outside
入力の1行目で、Regexp :: Assembleがパターンを再配置したことに注目してください。それは、私が追加したパーツのほんの一部を接着しただけではありません。
Regex is (?^:(?:[#$%&_]|\{|\}))
There are \$100 dollars
Part \#1234
Outside \{ inside \} Outside
さらに文字を追加したい場合は、その文字を@specials
。他のすべてはあなたのために起こります。
$
は、正規表現で特別な意味を持っています。つまり、「文字列の終わり」です。あなたはこのようなものでうまくいくでしょう:
# escape special characters, join them into a single line
my $chars = join '', map { "\\$_" } keys %special_characters;
$string =~ s/([$chars])/$special_characters{$1}/g;
また、Perlは"$"
をあまり好きではありません。'$'
を使用することをお勧めします(一重引用符=>補間なし)。
PDATE:すみません、急いでこれを書いていました=>編集が多すぎます:(