2013-03-24 55 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