まくまくPerlノート
文字単位で置換する
2008-03-13

文字単位の置換 (tr/AAA/BBB/)

$line =~ tr/SEARCHLIST/REPLACEMENTLIST/[OPTION]

という構文で、文字列 $line に含まれる文字群 (SEARCHLIST) を REPLACEMENTLIST に置換して $line に書き戻すことができます。 対象となる文字列が $_ である場合は、$line =~ の部分は省略することができます。

tr/// のオプション

オプション 何の略称か 意味
c complement 検索リストに文字の補集合を使う
d delete 検索リストにあり変換リストにないものを全て消す
s squeeze 変換して同じ文字になった場合1文字に縮める

例: A を X に、B を Y に、C を Z に置換する

$line =~ tr/ABC/XYZ/;

最後の文字の繰り返し

REPLACEMENTLIST が SEARCHLIST よりも短い場合は、REPLACEMENTLIST の最後の文字が繰り返し使用されます。

tr/a-f/ABC/;  # tr/a-f/ABCCCC/ とみなされる

上の場合は、

a → A
b → B
c → C
d → C
e → C
f → C

とそれぞれの文字が置換されることになります。 ただし、オプションに d を指定した場合は、対応文字がない文字は削除されるという振る舞いに変化します。

tr/a-f/ABC/d;  # 'd' 'e' 'f' は消える
a → A
b → B
c → C
d → 削除
e → 削除
f → 削除

変換リストが空の時

変換リストが空の時は、置換リストと同じ文字列が使われます。

tr/A-Z//;  # tr/A-Z/A-Z/;

つまり上のようにした場合は、$_ に何の変化も起こりません。 A ~ Z の文字を消したい時は、d オプションを指定しなければいけません。

戻り値を利用して文字数を数える

$count = tr/0-9//;    # 数字の文字数を数える
$count = tr/0-9//d;   # 数字を消す
$count = tr/0-9//c;   # 数字以外の文字数を数える
$count = tr/0-9//cd;  # 数字以外を消す

s オプションの利用例

以下の例は s オプションを使って、アルファベット以外の連続した文字を \n に置き換えます。 これで英単語をリストアップできます。

while (<>) {
    tr/A-Za-z/\n/cs;  # (\n)英単語\n英単語\n英単語\n ...
    s/^\n//;          # 先頭に \n があれば削除
    print;
}
2008-03-13