我试图使用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;
答案 0 :(得分:20)
试试这个:
my %special_characters;
$special_characters{"_"} = "\\_";
$special_characters{"\\\$"} = "\\\$";
$special_characters{"{"} = "\\{";
$special_characters{"}"} = "\\}";
$special_characters{"#"} = "\\#";
$special_characters{"%"} = "\\%";
$special_characters{"&"} = "\\&";
看起来很奇怪,对吗?您的正则表达式需要如下所示:
s/\$/\$/g
在正则表达式的第一部分中,“$”需要被转义,因为它是一个特殊的正则表达式字符,表示字符串的结尾。
正则表达式的第二部分被视为“普通”字符串,其中“$”没有特殊含义。因此,反斜杠是一个真正的反斜杠,而在第一部分,它用于逃避美元符号。
此外,在变量定义中,您需要转义反斜杠以及美元符号,因为它们在双引号字符串中都有特殊含义。
答案 1 :(得分:3)
如果您用自己的反斜杠替换每个字符,则不需要哈希。只需匹配您需要的内容并在其前面添加反斜杠:
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
请注意,在第一行输入中,Regexp :: Assemble重新排列了我的模式。这不只是我添加的部分粘合在一起的部分:
Regex is (?^:(?:[#$%&_]|\{|\}))
There are \$100 dollars
Part \#1234
Outside \{ inside \} Outside
如果您想添加更多字符,只需将字符放在@specials
中即可。其他一切都发生在你身上。
答案 2 :(得分:0)
$
在regexp中有特殊含义,即“字符串结束”。你最好用这样的东西:
# escape special characters, join them into a single line
my $chars = join '', map { "\\$_" } keys %special_characters;
$string =~ s/([$chars])/$special_characters{$1}/g;
另外,perl不喜欢"$"
,更好地使用'$'
(单引号=&gt;无插值)。
更新:抱歉,我写这篇文章的时间很快=&gt;太多编辑:(