2013-03-24 64 views
0

/c修饰符在我不明白的地方做了些什么。我想知道为什么下面的代码会打印“abc3333”?在Perl中使用/ c修饰符的奇数tr ///操作符行为

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

这是一个有效的问题,但措辞可能很差。音译中的'/ c'修饰符代表“complement”,这在perlop中解释'“如果指定了/ c修饰符,那么SEARCHLIST字符集就会被补充。”'这确实是一个很弱的解释。基本上,它意味着音译任何不匹配“abc”的字符。 – TLP 2013-03-24 13:47:59

+0

谁从这个问题的标题中删除了“tr”?如何在Perl中使用?如何在任何地方使用有效的问题? – TLP 2013-03-24 13:50:02

+0

也许你会更多的机会了解它,如果你阅读文档 - http://perldoc.perl.org/perlop.html :-) – 2013-03-25 10:37:51

回答

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 
+0

ysth:你在'tr/abc // c'写错了,右边是'tr/abc// c' – baozailove 2013-03-25 02:07:53

+1

@baozailove:不,用空格将所有nul字符改为空格。只有一个空的替换列表(和no/d)才能成为一个计数操作符。你为什么认为应该有一个空间? – ysth 2013-03-25 02:31:38

+0

to ysth:你说'tr/abc // C#returns非abc字符的数量;',但是我执行返回'abcdefg'的代码并且不返回'没有abc字符' – baozailove 2013-03-25 13:13:06

0

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

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

输出

def 
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命令行工具完全一致。我不确定如果没有/d/c可能永远不会有用,但也许是tr命令行工具已超过tr///(如字符类)的额外功能。

+0

我发现这有点混乱,所以添加了我自己的答案:) – ysth 2013-03-24 16:27:27

+0

@ysth它甚至不是正确的,但现在已经修复了 – ikegami 2013-03-24 22:41:41

+0

@ikegami:为什么'a'是字符0x61? – baozailove 2013-03-25 02:26:58