はじめに
Rubyで文字列置換を行う際に大活躍するgsubメソッドですが、ブロックを用いた使用方法があることを知りました。
便利だと思ったので記事にして紹介しようと思います。
gsubの基本的な使い方
まずは基本的な使用方法から見ていきましょう。
第一引数には文字列および正規表現を渡すことができ、第二引数には第一引数にマッチしたパターンを置換する文字列を渡します。
まずは文字列をマッチさせるケースから書いてみます。
original = 'わたしはイヌを飼っています。わたしが飼っているイヌの名前は太郎です。'
replaced = original.gsub('イヌ', 'ネコ')
puts replaced
# => 'わたしはネコを飼っています。わたしが飼っているネコの名前は太郎です。'
このように、第一引数の文字列(イヌ)に合致する箇所全てを第二引数の文字列(ネコ)に置換した結果を返却します。
同様に、第一引数に正規表現を使用した例を考えてみます。
original = 'わたしは2024年生まれです。電話番号は123-456-789です。'
replaced = original.gsub(/[0-9]/, '*')
puts replaced
# => 'わたしは****年生まれです。電話番号は***-***-***です。'
[0-9]は任意の整数を表す正規表現です。今回は文中の数字を全て*に置き換えることで、個人情報を隠すプログラムを想定してみました。
[余談]破壊的メソッド
今回のテーマとは少し離れてしまいますが、gsub
には破壊的メソッドgsub!
があります。
gsub
は元の文字列には変更を加えないのに対して、gsub!
は元の文字列に変更を加えてしまいます。
original = 'わたしはイヌを飼っています。わたしが飼っているイヌの名前は太郎です。'
original.gsub!('イヌ', 'ネコ')
puts original
# => 'わたしはネコを飼っています。わたしが飼っているネコの名前は太郎です。'
ブロックを使用してみる
今までの例は比較的わかりやすい例でしたが、もう少し複雑な例をみてみましょう。
例その1
例えば、以下の文字列を置換することを考えて見ます。
'I have a dog. His name is Taro.'
この分のdogを大文字にしたい時、どうやって書きますか?
ブロックを使用するとこれがシンプルに実現できます。
original = 'I have a dog. His name is Taro.'
replaced = original.gsub('dog') {|s| s.upcase}
puts replaced
# => 'I have a DOG. His name is Taro.'
このように、パターンマッチした箇所を順番にブロックに渡し、その実行結果で置き換えた文字列を生成して返します。
これを使用することでより複雑な文字列置換処理でもシンプルに書くことが可能です。
例その2
以下のような文章があると考えてみます。
original = <<~EOS
名前: 田中
職業: 会社員
掲載: 可
------------
名前: 山田
職業: 自営業
掲載: 不可
------------
名前: 鈴木
職業: 専業主婦
掲載: 可
------------
EOS
ここから、掲載可能なプロフィールだけを残し、掲載不可の人のプロフィールを非公開にするプログラムを作成してみます。
作戦は以下の通りです。
- 各人のプロフィール(名前: xxxの部分から------------の部分まで)を読み込む
- プロフィール部分に
掲載: 不可
の記述があるかどうかを判定する -
掲載: 不可
の場合は「このプロフィールは非公開です」に置換、そうでない場合はプロフィールをそのまま残す
いざ実装
original.gsub!(/(名前: .*?------------)$/m) do |profile|
# 正規表現にマッチした部分がprofileとしてブロックに渡される
# 掲載: 不可の記述がある場合は置換、ない場合はそのまま返却
profile.include?('掲載: 不可') ? "このプロフィールは非公開です\n------------" : profile
end
結果
名前: 田中
職業: 会社員
掲載: 可
------------
このプロフィールは非公開です
------------
名前: 鈴木
職業: 専業主婦
掲載: 可
------------
無事に掲載: 不可
の人のプロフィールを隠すことができましたね。
感想
普段からよく使用するメソッドでもまだまだ知らない使い方があるのだなと思いました。
これに懲りずにまだまだ精進したい所存です。
では、良いお年を。
参考