0
0

【Ruby】sub・gsub・tr で文字を置換しよう!(tr と gsub の相違点)

Last updated at Posted at 2024-09-12

概要

subなどのメソッドを使用すると任意の文字を置換可能
stringのみ可能

text = "今日はピクニックに行けなかった..."

# 引数を指定することで文章を置換
text = text.sub("行けなかった...", "行った!")

p text

# result
"今日はピクニックに行った!"
# 直接要素につけることも可能
p "hamburger".sub("burger", "ster")

# result
"hamster"


# Integerには不可能なので注意
p 4444444.gsub(4, 0)

# result
=> : undefined method `gsub' for 4444444:Integer (NoMethodError)

sub

sub(第一引数, 第二引数)
・初めに第一引数にマッチした文字列だけを第二引数の値に置換
・再代入必要

text = "ハンターハンター"

text = text.sub("ハンター", "モンスター")

p text

# result
"モンスターハンター"

gsub

gsub(第一引数, 第二引数)
・第一引数にマッチした文字列を全て第二引数の値に置換
・再代入必要

text = "ハンターハンター"

text = text.gsub("ハンター", "モンスター")

p text

# result
"モンスターモンスター"

下記のように書くと便利

text = "あなたの負けです"

text = text.gsub(/あなた|負け/, "あなた" => "私", "負け" => "勝ち")

p text

# result 
"私の勝ちです"

sub!

sub!(第一引数, 第二引数)
・破壊的にsubを行う
・元の値を変えるため再代入不必要

animals = "cat dog rabbit"

# subは再代入しない限り元の変数は変わらない
animals.sub("cat", "human")
p animals

# result
"cat dog rabbit"


# sub!は元の変数自体を変える
animals.sub!("cat", "human")
p animals

# result
"human dog rabbit"

tr

tr(第一引数, 第二引数)
・基本的にはgsubと同じ
・再代入必要
一文字づつ置き換える

p "グッドモーニング".tr("モーニング", "イブニング")

# result
"グッドイブニング"


# 全て大文字に揃える
p "aBCdEfgHi".tr('a-z', 'A-Z')

# result
"ABCDEFGHI"


# メールアドレスを半角化
email = "TEST−mail@example.com"
p email.tr("0-9a-zA-Z.@−", "0-9a-zA-Z.@-")

# result
"TEST-mail@example.com"

trとgsubの相違点

同じ点
・文全体を置換できる

違う点
・変更の途中経過
・変更の方法

# oo → in に直接変えている
p "food".gsub("oo", "in")

# 「o → i」「o → n」を順番に読み込む、今回は「o → n」が最後に読み込まれたのでoは全てnになる
p "food".tr("oo", "in")

# result
"find"
"fnnd"

もっと詳しく数字で

# gsubでは...
p "1000001".gsub("00", "0")    # [00 -> 0] なので「 00 00 0 -> 0 0 0 」 

p "1000001".gsub("00", "0a")    # [00 -> 0a] なので「 00 00 0 -> 0a 0a 0」

p "1000001".gsub("00", "0ab")    # [00 -> 0ab] なので「 00 00 0 -> 0ab 0ab 0」

p "1000001".gsub("100", "0ab")    # [100 -> 0ab] なので「 100 -> 0ab 」

# result
"10001"
"10a0a01"
"10ab0ab01"
"0ab0001"


# trでは...
p "1000001".tr("00", "0")     # 1️⃣[0 -> 0] 2️⃣[0 -> 0](変更点上書き) 変更するのは:[0 -> 0]
                              # 「 0 0 0 0 0 -> 0 0 0 0 0 」
                              
p "1000001".tr("00", "0a")    # 1️⃣[0 -> 0] 2️⃣[0 -> a](変更点上書き) 変更するのは:[0 -> a]
                              # 「 0 0 0 0 0 -> a a a a a 」 
                              
p "1000001".tr("00", "0ab")   # 1️⃣[0 -> 0] 2️⃣[0 -> a](変更点上書き) 変更するのは:[0 -> a]
                              # 「 0 0 0 0 0 -> a a a a a 」 
                              
p "1000001".tr("100", "0ab")  # 1️⃣[1 -> 0] 2️⃣[0 -> a] 3️⃣[0 -> b](変更点上書き) 
                              # 変更するのは:[1 -> 0] [0 -> b] 
                              # 「 1 0 0 0 0 0 1 -> 0 b b b b b 0 」 

# result
"1000001"
"1aaaaa1"
"1aaaaa1"
"0bbbbb0"

:thinking:

ややこしい

個人的には
・特定の一文字 → 一文字の場合(例:¥ を \ にする)は tr
・普段使い、二文字以上の場合(例:要素2つ以上 "\n\n" を要素1つ "\n" にする)は gsub

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0