【Ruby】文字列置換メソッドsub()とgsub()を使いこなそう

  • 2021年7月7日
  • 2021年10月16日
  • Ruby

Rubyで文字列関連の処理を実装する際、文字列の置換処理を実装する場面に出くわすことがあります。一見すると難しそうに思えますが、文字列の置換処理はあるメソッドを呼び出すことで、簡単に実現できます。そのメソッドとは、sub()メソッドとgsub()メソッドです。

今回は、文字列の置換処理を実装するならぜひ覚えておきたい、sub()メソッドとgsub()メソッドの使用方法について、詳しく解説していきます。

それぞれ、メソッドの振る舞いにどのような違いがあるのかについても、サンプルコード付きで解説しますので、文字列の置換処理を実装する際の参考にしてみてください。

なお、Rubyの魅力や特徴については以下の記事で詳しく解説していますので、こちらもぜひご覧くださいね。

おすすめ記事

みなさんこんにちは! 今回の記事は、 悩みを抱えた人 ・Rubyってどんなプログラミング言語なの?・Rubyを勉強すると将来役に立つかな?・Rubyのおすすめの学習方法が知りたい! というお悩みを解決する記事にな[…]

Rubyとは?その特徴や将来性、おすすめの学習方法まで網羅的にご紹介します

レバテックフリーランス … 業界最大級の案件数業界トップクラスの高単価報酬を誇る最大手のサービスです。実績豊富なコーディネーターが丁寧な対応をしてくれるため、案件の無理な提案はありません。フリーランスで生きていくためにはまず登録しておきましょう。
MidWorks … フリーランス賠償責任保障生命保険の折半など、フリーランスでありながらも正社員並みの保障を受けられるのが特徴です。また、経験豊富なキャリアコンサルタントによる手厚いサポートも受けられるため、安定したフリーランス生活を送りたい方には特におすすめのサービスです。
ポテパンフリーランス … IT業界・技術に詳しいコンサルタントが担当してくれるため、こちらの要望をきちんと理解した上で案件を紹介してくれます。また、案件情報のみならず、フリーランスのイロハについても教えてくれるため、フリーランスとして初めて活動される方には特におすすめのサービスです。

レバテックキャリア … ITエンジニアが利用したい転職エージェントNo.1にも選ばれており、年収600万円以上のハイクラス求人を5,000件以上も保有しています。エンジニアが転職を考えた時にまず初めに登録しておくべきサービスです。
Tech Stars Agent … Tech Stars Agentでは、担当エージェントが全員エンジニア出身のため、スキルやキャリアを見据えたきめ細かな転職支援が受けられます。運営元の株式会社Branding Engineerは、独立支援サービス「MidWorks」も展開しているため、独立を視野に入れたサポートも受けられます
転職ドラフト … 年収UP率93.8%/平均年収UP額126万円と圧倒的な年収UP率を誇るイベント型のエンジニア向け 転職サービスです。毎月1回開催され、厳選された優良IT/Web系企業約150社からダイレクトスカウトを受け取ることができます。年収アップを目指す方は登録必須です。


sub()メソッドとgsub()メソッドの違い

Rubyでは、文字列の置換処理を実行するメソッドとして、sub()メソッドとgsub()メソッドの2つが用意されています。それぞれのメソッドの違いを簡単に述べると、以下の表の通りです。

メソッド内容
sub()置換対象の文字列のうち、最初に出現するものを置き換える
gsub()置換対象の文字列を全て置き換える

実際に、以下のサンプルコードを実行して動作の違いを確認してみましょう。

article = "This is an apple. The apple is very delicious. Do you like this apple?"

# sub()メソッドで文字列を置換
article_replaced_1 = article.sub("apple", "orange")

# gsub()メソッドで文字列を置換
article_replaced_2 = article.gsub("apple", "orange")

p article_replaced_1 # "This is an orange. The apple is very delicious. Do you like this apple?"
p article_replaced_2 # "This is an orange. The orange is very delicious. Do you like this orange?"

「apple」が3つ含まれている文字列articleに対して、sub()メソッドとgsub()メソッドで「apple」から「orange」への文字列置換処理を実施するプログラムを実装しています。

sub()メソッドで置換した文章は、最初に出現する「apple」のみが「orange」に置き換わっており、以降の文章中に出現する「apple」は置き換わっていません。

一方、gsub()メソッドで実行した場合は、文章中の全ての「apple」が置き換わっていないことが分かります。

sub()メソッド・gsub()メソッドの基本的な使用方法

ここからは、sub()メソッドとgsub()メソッドの引数や戻り値などの詳細な内容について解説していきます。

sub()メソッド・gsub()メソッドは、いずれも2つの引数を持ちます。

第一引数置換前の文字列第二引数置換後の文字列です。例えば「This is a pen.」の「pen」を「eraser」に置き換えたいのであれば、第一引数に「pen」、第二引数に「eraser」を設定します。

第一引数の置換前の文字列は、正規表現による記法に対応しています。正規表現は、文字列の検索や置換処理で利用される特殊な文字列パターンです。簡単な正規表現を使った、文字列置換処理のサンプルコードを以下に示します。

alphabet = "abcdefg abcdefg"

# 通常の文字列リテラルによる文字列置換処理
replaced_str_1 = alphabet.sub("cd", "CD")
replaced_str_2 = alphabet.gsub("cd", "CD")

p replaced_str_1 # "abCDefg abcdefg"
p replaced_str_2 # "abCDefg abCDefg"

# 正規表現による文字列置換処理
replaced_str_3 = alphabet.sub(/cd/, "CD")
replaced_str_4 = alphabet.gsub(/cd/, "CD")

p replaced_str_3 # "abCDefg abcdefg"
p replaced_str_4 # "abCDefg abCDefg"

置換前の文字列を正規表現で表現する場合は、置換前の文字列をスラッシュで囲むように記載します。サンプルコードでは、「cd」を「CD」に置き換えるために「/cd/」と記述して引数に渡しています(11,12行目)。

破壊的メソッドとの違い

sub()メソッドとgsub()メソッドの派生メソッドとして、sub!()メソッドとgsub!()メソッドが用意されているのをご存じでしょうか。このビックリマーク付きのメソッドはRubyにおいて「破壊的メソッド」と呼ばれています。

対して、ビックリマークの付かないメソッドは「非破壊的メソッド」と呼ばれています(一部例外あり)。両者の違いを、以下のサンプルコードで確認してみましょう。

article_1 = "There are many fruits"
article_2 = "There are many fruits"
article_3 = "Please give me a yellow pen, a black pen, a red pen"
article_4 = "Please give me a yellow pen, a black pen, a red pen"

# 非破壊的メソッド
replaced = article_1.sub(/fruits/, "vegetables")
replaced = article_3.gsub(/pen/, "shirt")

# 破壊的メソッド
article_2.sub!(/fruits/, "vegetables")
article_4.gsub!(/pen/, "shirt")

# 非破壊的メソッド:呼び出し元のオブジェクトは変化しない
p article_1 # "There are many fruits"
p article_3 # "Please give me a yellow pen, a black pen, a red pen"

# 破壊的メソッド:呼び出し元のオブジェクトが変化する
p article_2 # "There are many vegetables"
p article_4 # "Please give me a yellow shirt, a black shirt, a red shirt"

上記サンプルコードを実行してみると、破壊的メソッドを利用したパターンでは、呼び出し元の文字列自体が置換処理の対象となっていることが分かります。

置換後の文字列を新しく変数に格納するほどでもないようなケースであれば、破壊的メソッドで置換処理を実装することで、余計なメモリを確保せずに済みます。

sub()メソッドとgsub()メソッドの応用テクニック

基本的な使い方を理解しておくだけでも、文字列の置換処理は実装できます。しかし、ここから紹介するテクニックを駆使すれば、さらに複雑な置換処理を実装するスキルを身につけられます。

元の文字列を残しつつ置換する

元の文字列にカギ括弧を付与したいなど、元の文字列を残しつつ文字を追加したい場合は、sub()メソッド・gsub()メソッドの引数に「\&」を利用して、以下のサンプルコードのように記述します。

article_1 = "これはリンゴです。"
article_2 = "彼は佐藤太郎です。佐藤太郎はサッカーが上手です。"

# \&には置換前の文字列が入ります
replaced_article_1 = article_1.sub(/リンゴ/, '「\&」')
p replaced_article_1 # "これは「リンゴ」です。"

replaced_article_2 = article_2.gsub(/佐藤太郎/, '「\&」')
p replaced_article_2 # "彼は「佐藤太郎」です。「佐藤太郎」はサッカーが上手です。"

\&置換前の文字列を示す特別な記号です。サンプルコードの5行目では「リンゴ」という単語にカギ括弧を付与する置換処理を実行しています。

置換処理を細かく記述する

ブロックと呼ばれる仕組みを利用すれば、条件や計算などを加味した、より複雑な置換処理を表現できます。

例えば、文章中に表記されている税抜価格を税込価格に書き換えたいとしましょう。価格によって置換後の文字列が異なるため、事前に税込価格を計算しなければなりません。そこで、ブロックを利用して以下のサンプルコードにように記述すれば、目的の処理を実装できます。

products = "シャツ:3100円、腕時計:20000円、万年筆:7000円"

replaced = products.gsub(/(\d+)円/) {
  # to_iメソッドで数値に変換し税率をかける
  price = $1.to_i * 1.1
  # floorメソッドで小数点以下を切り捨て
  price = price.floor
  # to_sメソッドで文字列に変換
  str = price.to_s + "円"
}

p replaced # "シャツ:3410円、腕時計:22000円、万年筆:7700円"

ブロックを利用すれば、gsub()メソッドの呼び出し時に、データ型の変換処理や税込価格の計算処理などを実行できます。

ブロック内の「$1」は、置換前の文字列を示す特別な記号で、通常の変数と同じように取り扱うことができます。ブロックを利用した置換処理では、ブロック内の最後に格納された変数(サンプルコードでは変数strが該当)が、最終的な置換結果として返されることを覚えておきましょう。

一回の呼び出しで複数の置換処理を実行する

置換処理のパターンが複数存在し、sub()メソッドやgsub()メソッドを何度も呼び出すことが想定される場合は、ハッシュと呼ばれる仕組みを利用することで、一度の呼び出しで複数パターンの置換処理を一括実行できます。

ハッシュとは、キーと値を記号「=>」で対応させ、それを配列のように列挙したデータ構造です。例えば、以下のようなデータ構造がハッシュに該当します。

book_price = { "Ruby入門" => 1900, "Rubyで実践プログラミング" => 2100, "Ruby on Rails入門" => 3100 }

ハッシュの仕組みを利用すれば、「置換前文字列 => 置換後文字列」のようにデータを定義することで、置換処理のパターンを複数定義することができ、引数に渡すことで一括処理が実行できます。サンプルコードは、以下の通りです。

article = "I like travel, rock and soccer."

# 置換処理パターンをハッシュで定義
# 形式: { 置換前文字列 => 置換前文字列, ... }
pattern = { "rock" => "J-pop", "soccer" => "baseball" }

replaced = article.gsub(/rock|soccer/, pattern)

p replaced # "I like travel, J-pop and baseball."

文章中の「rock」「soccer」をそれぞれ「J-pop」「baseball」に置き換える処理をgsub()メソッドで実装しています。

パターンが2つあるので、gsub()メソッドを2回呼び出しても良いですが、ここではハッシュを利用して置換前後の文字列を対応付けしたデータを定義した(5行目)後に、gsub()メソッド一回の呼び出しで一括で置換処理を施す方法を採用しています。

お仕事の途中ですが、少し一休みして、転職独立について考えてみませんか🙌?

現役エンジニアが選ぶおすすめの転職エージェント11選【成功談・失敗談もあります】

レバテックフリーランスの評判ってどう?【現役エンジニアが徹底解説します】

MidWorks(ミッドワークス)の評判ってどう?【現役エンジニアが徹底解説します】

日々の業務に追われて自分を見失わないよう、
定期的にキャリアを振り返るようにしておきましょう🤲

最後に

さて、ここまでRubyで文字列の置換処理を実装する方法(sub()メソッド・gsub()メソッド)について解説してきましたがいかがでしたか?

こうして体系的に整理してみると、それほど難しい内容ではないことがお分かりいただけたかと思います。

今回の記事でしっかりとマスターして、今後の開発でも積極的に使っていってくださいね。

このブログを通じて少しでも「傍(はた)を楽(らく)にする」ことができていれば嬉しく思います。

最後まで読んで頂きありがとうございました。