Rubyで文字列関連の処理を実装する際、文字列の置換処理を実装する場面に出くわすことがあります。一見すると難しそうに思えますが、文字列の置換処理はあるメソッドを呼び出すことで、簡単に実現できます。そのメソッドとは、sub()メソッドとgsub()メソッドです。
今回は、文字列の置換処理を実装するならぜひ覚えておきたい、sub()メソッドとgsub()メソッドの使用方法について、詳しく解説していきます。
それぞれ、メソッドの振る舞いにどのような違いがあるのかについても、サンプルコード付きで解説しますので、文字列の置換処理を実装する際の参考にしてみてください。
なお、Rubyの魅力や特徴については以下の記事で詳しく解説していますので、こちらもぜひご覧くださいね。
みなさんこんにちは! 今回の記事は、 悩みを抱えた人 ・Rubyってどんなプログラミング言語なの?・Rubyを勉強すると将来役に立つかな?・Rubyのおすすめの学習方法が知りたい! というお悩みを解決する記事にな[…]
フリーランス案件を探すならこのエージェント!
転職を考えているならこのエージェント!
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()メソッド)について解説してきましたがいかがでしたか?
こうして体系的に整理してみると、それほど難しい内容ではないことがお分かりいただけたかと思います。
今回の記事でしっかりとマスターして、今後の開発でも積極的に使っていってくださいね。
このブログを通じて少しでも「傍(はた)を楽(らく)にする」ことができていれば嬉しく思います。
最後まで読んで頂きありがとうございました。