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

  • 2021年7月7日
  • 2021年12月19日
  • Ruby

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

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

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

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

おすすめ記事

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

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

フリーランス案件を探すならこのエージェント!

運営会社 レバテック株式会社 株式会社Branding Engineer 株式会社Hajimari
対応エリア 東京・神奈川・埼玉・千葉
大阪・兵庫・京都・愛知・福岡
東京・神奈川・埼玉・千葉
大阪・兵庫・京都・奈良・和歌山・滋賀
東京・神奈川・埼玉・千葉
茨城・大阪・兵庫・福岡
案件数 約28,000件 約3,300件 約4,200件
平均単価 68.2万円 72.2万円
最高月収 145万円 200万円 176万円
支払いサイト 15日(月末締め翌月15日支払い) 20日
手数料(中間マージン) 非公開 非公開
※実質20%
非公開
特徴高単価な案件が多い
福利厚生サービスが受けられる
・首都圏の案件が中心
給与保証制度で安定した収入を得られる
・税務処理のサポートあり
・マージン率は実質20%
週2/週3の案件が多い
在宅/リモート案件が多い
・スタートアップ企業やベンチャー企業の案件が多い
紹介企業例 ・株式会社Gunosy
・株式会社バンダイナムコホールディングス
・株式会社ユーザベース
・Sansan株式会社
・株式会社一休
・株式会社FiNC Technologies など
・クックパッド株式会社
・株式会社カオナビ
・株式会社Kaizen Platform など
説明記事
公式サイト


転職を考えているならこのエージェント!

運営会社 レバテック株式会社 株式会社Branding Engineer 株式会社リブセンス
対応エリア 東京・神奈川・埼玉・千葉
大阪・兵庫・京都・愛知・福岡
東京・神奈川・埼玉・千葉
大阪・兵庫・京都・奈良・和歌山・滋賀
東京・神奈川・埼玉・千葉
茨城・大阪・兵庫・福岡
案件数 約13,000件 約800件
※非公開求人が多い

※ドラフト制のため、対象外
年齢層 20代:◎
30代:〇
40代:〇
20代:〇
30代:〇
40代:△
20代:〇
30代:〇
40代:〇
特徴エンジニア・デザイナーを専門としている
・カウンセリングに時間をかける
年収アップ率60%の実績
IT/Web/ゲーム業界専門の転職エージェント
・業界経験者がキャリアコンサルタントを務める
・丁寧なカウンセリングで入社後の離職率1%以下を実現
ドラフト制による採用を叶える特殊なサービス
スキル・経験重視で評価してもらえる
・他エンジニアの入札結果を見ることで
自分の市場価値が分かる
紹介企業例 ・サイボウズ株式会社
・株式会社サイバーエージェント
・Chatwork株式会社 など
・DMM.com
・Money Forward
・SmartHR など
・メルカリ
・ZOZOテクノロジーズ
・freee など
説明記事
公式サイト



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()メソッド一回の呼び出しで一括で置換処理を施す方法を採用しています。

最後に

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

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

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

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

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