tr///, y///

文字列を置換する

構文

解説

tr///y///SEARCHLIST に列挙された文字リストの文字を、 REPLACEMENTLIST に列挙された文字リストの文字に置き換えます。

次の例は、大文字アルファベットを小文字アルファベットに変換します。

my $str = 'Perl is great.';
$str =~ tr/a-z/A-Z/;
print $str;    # "PERL IS GREAT."

utf8 フラグが ON の内部文字列であれば、日本語のようなマルチバイトの文字を扱うこともできます。 次の例はひらがなをカタカナに変換します。

use utf8;
binmode STDOUT, ":utf8";

my $str = 'ゔぁーじょん';
$str =~ tr/ぁ-ゔ/ァ-ヴ/;
print $str;    # "ヴァージョン"

ひらがな全体やカタカナ全体を表現する場合、Unicode のコードポイント順にする必要がありますので注意してください。 ひらがなは「ぁ」(小さい「あ」) にはじまり「ゔ」で終わります。 同様に、ひらがなに対応するカタカナも「ァ」(小さい「ア」) に始まり「ヷ」で終わります。

基本的に SEARCHLISTREPLACEMENTLIST に記述される文字数が一致するように使います。 しかし、もし REPLACEMENTLIST に何も指定がない場合は、何も変換が発生しません。

my $str = 'Hello, again';
$str =~ tr/a-zA-Z//;
print $str;    # "Hello, again"

REPLACEMENTLIST に一つの文字が指定されると、SEARCHLIST に一致した文字はすべて REPLACEMENTLIST の文字に置き換わります。

my $str  = 'Hello, again';
$str =~ tr/a-zA-Z/a/;
print $str;     # "aaaaa, aaaaa"

もし REPLACEMENTLIST に 2 文字以上が存在する場合、REPLACEMENTLIST に対応する文字がなければ、 REPLACEMENTLIST の最後の文字に置換されます。

my $str = 'Hello, again';
$str =~ tr/a-zA-Z/ab/;
print $str;    # "bbbbb, ababb"

オプション修飾子

tr///y/// には最後にオプションを指定することができます。

オプション 説明
c

文字を変換した後、連続する文字を 1 つにします。

my $str = "aaabbbca";
$str =~ tr/ab/dd/s;
print $str;    # "dcd"

この例では、まず ad に、bd に変換されます。 すると文字列 aaabbbcaddddddca に変換されます。 この中から連続する同じ文字 d を 1 つにします。すると dcd になります。

d

SEARCHLIST に対応する文字が REPLACEMENTLIST にない場合、その文字は削除します。

my $str = 'Hello, again';
$str =~ tr/A-Z/a-c/d;
print $str;    # "ello, again"

この例では A-Z を a-c に変換しますが、D-Z は変換先が定義されていません。 d が指定されていると、そららの文字は削除されます。

r

オリジナルの文字列は変換をせずそのままにして、変換した文字列を別の変数にセットできます。

my $str  = 'Hello, again';
my $str2 = $str =~ tr/a-z/A-Z/r;
print $str;     # "Hello, again"
print $str2;    # "HELLO, AGAIN"

この例では、オリジナルの文字列となる変数 $str の値は変換されません。 その代わり変数 $str2 に変換後の文字列がセットされます。

s

置換の対象になった文字が連続していれば、それを一つにします。 実際には次のように連続重複文字を 1 つにするために使われることが多いでしょう。

my $str = 'aaabbbcccAAABBBCCC';
$str =~ tr/a-zA-Z//s;
print $str;    # "abcABC"

SEARCHLISTREPLACEMENTLIST に変数を使う

tr///, y/// は、コンパイル時に変換テーブルを構築してしまうため、 SEARCHLISTREPLACEMENTLIST の中では変数展開ができません。 もしどうしても変数を使いたい場合は、eval を使ってください。

my $search      = 'a-z';
my $replacement = 'A-Z';
$_ = 'Hello, again';
eval "tr/$search/$replacement/" or die $@;
print $_;

$_ ではなく、通常の変数を使いたい場合は、次のようにします。

my $search      = 'a-z';
my $replacement = 'A-Z';
my $str         = 'Hello, again';
eval "\$str = tr/$search/$replacement/" or die $@;
print $str;