Just do IT

思うは招く

Ruby String#tr の挙動を確かめた

RubyString#trについて調べた。

String#tr (Ruby 3.1 リファレンスマニュアル)

シンプルな使い方

まずはシンプルな例から見てみる。

> 'abc'.tr('a', 'd')
=> "dbc"

abcという文字列のうち、a を d に変換した。

もうひとつシンプルな例を見てみる。

> 'abc'.tr('c', 'f')
=> "abf"

abcという文字列のうち、c を f に変換した。

-で範囲指定をする

では、ひとつ踏み込んだ使い方をしてみる。

> 'abcde'.tr('a-e', 'f')
=> "fffff"

abcdeという文字列の、a から e までの範囲を f に変換した。-で範囲指定を指定できる。

以下のロジックと同じだ。

> 'abcde'.tr('abcde', 'f')
=> "fffff"

> 'abcde'.tr('a-e', 'f')
=> "fffff"

第2引数のほうでも-を使って範囲指定することができる。

> 'abcde'.tr('a-e', 'f-j')
=> "fghij"

abcdeという文字列の、a から e までの範囲を f から j までの範囲で変換した。つまり、

  • a は f に
  • b は g に
  • c は h に
  • d は i に
  • e は j に

それぞれ変換された。a から e までの文字が5つ、f から j までの文字が5つあることから、ちょうどすべての文字が変換された結果になった。

では、次の例ではどうなるか?

> 'abcde'.tr('a-e', 'f-g')

a から e までの文字列にたいして、今度は f から g までの2文字しか変換の設定をしていない。結果は次のようになる。

> 'abcde'.tr('a-e', 'f-g')
=> "fgggg"

結果:

  • a を f に変換した
  • b 以降の文字はすべて g に変わった

このように、第一引数と第二引数の文字列の数が合わない場合、第二引数の最後の文字がずっと続くものとして変換される。この挙動は公式リファレンスにも記載されている。

replace の範囲が pattern の範囲よりも小さい場合は、 replace の最後の文字が無限に続くものとして扱われます。

では、最後に次の例を見てみる。

> 'abcde'.tr('a-c', 'f-g')
=> "fggde"

abcdeという文字列の、a から c までの範囲を f から g までの範囲で変換した。つまり、

  • a が f に
  • b と c が g に

それぞれ変わった。