使用Perl中的/ c修饰符的奇数tr ///运算符行为

时间:2013-03-24 12:53:30

标签: perl tr

/c修饰符做了我在这里不明白的事情。我想知道为什么以下代码会打印“abc3333”?

#!/usr/bin/perl
$x = 'abcdefg';
$x =~ tr/abc/123/c;
print $x;

3 个答案:

答案 0 :(得分:3)

/c会导致搜索列表得到补充;也就是说,搜索列出的每个字符

假设您只有\0-\xff范围内的字符,请执行以下操作:

tr/abc/123/c

相当于:

tr/\0-\x60\x64-\xff/123/

并根据需要重复替换列表的最后一个字符,以匹配搜索列表中的字符数(不使用/ d时)。

所以" \ 0"成为" 1"," \ 1"成为" 2"," a"," b"或" c"没有变化,任何其他角色变为" 3"。

用/ c指定替换列表是相当罕见的;通常/ c仅用于计数:

tr/abc//c # returns number of non-abc characters; string is unchanged

或删除:

tr/0-9//cd # delete all non-digits

答案 1 :(得分:1)

/c通常用于修改/d

tr/...//d;    # Delete every matching char.
tr/...//cd;   # Delete every char that doesn't match.

或计算。

tr/...//;    # Returns number of matching chars.
tr/...//c;   # Returns number of chars that don't match.

我无法用非空替换集来提供一个有用的示例,但它很容易解释:它只是使用搜索集的补码。请注意abc是字符0x61,0x62和0x63,

tr/abc/123/c;
因此

等同于

tr/\x00-\x60\x64-\x{FFFFFFFFF}/123/;            # Perl with 32bit ints
  or
tr/\x00-\x60\x64-\x{FFFFFFFFFFFFFFFFFF}/123/;   # Perl with 64bit ints

请记住,替换集的最后一个字符用于搜索集中没有相应字符的字符,

  • "\x00"变为1
  • "\x01"变为2
  • 匹配的其他所有内容都会变为3

此行为与tr所基于的tr///命令行工具完全一致。我不确定/c如果没有/d会如何有用,但可能是tr命令行工具超过tr///的额外功能(例如字符)类)。

答案 2 :(得分:0)

/c修饰符会影响列表中字符的补充。它主要与/d修饰符一起使用,删除除一组给定字符之外的所有字符。

my $string = 'ABCdef123';
$string =~ tr/a-z//cd;
print $string;

<强>输出

def