perl在使用tr //运算符时给出不同的结果

时间:2016-02-04 13:01:13

标签: perl

为什么perl会在下面给出不同的结果?

$a = "bar";
$a =~ tr/abc/ABC/d;
print "[$a]\n"; # prints "BAr" as expected.

$x = "bar";
$y = "abc";
$z = "ABC";
$x =~ tr/\\Q$y\\E/\\Q$z\\E/d;
print "[$x]\n"; # prints "bar" to my surprise.

同样还有一个测试用例如下:

$p = "--aaa--";
$q = "abc-";
$r = "ABC";
$p =~ tr/\\Q$q\\E/\\Q$r\\E/d;
print "[$p]\n"; # prints "--aaa--" surprisingly.

$s = "--aaa--";
$s =~ tr/abc-/ABC/d;
print "[$s]\n"; # prints "AAA" as expected.

有人可以解释一下这种行为吗?

最诚挚的问候, 穆罕默德·安瓦尔

1 个答案:

答案 0 :(得分:4)

tr///没有插值。

tr/\\Q$y\\E/\\Q$z\\E/d翻译

  • \\
  • QQ
  • $$
  • yz
  • EE

$x不包含任何这些字符,因此它保持不变。

tr/\\Q$q\\E/\\Q$r\\E/d翻译

  • \\
  • QQ
  • $$
  • qr
  • EE

$p不包含任何这些字符,因此它保持不变。

要获得所需的行为,您可以使用

my %tr;
@tr{ split(//, $fr) } = split(//, $to);
$_ //= '' for values %tr;
my $re = '['.( join '', map quotemeta, keys %tr ).']';
$s =~ s/($re)/$tr{$1}/g;

eval "\\$s =~ tr/\Q$fr\E/\Q$to\E/d";
die $@ if $@;