スキップしてメイン コンテンツに移動

Ruby正規表現応用術

Ruby正規表現応用術

正規表現の基礎

Rubyで正規表現を扱う際の基本構文は、Regexpクラスを利用します。最も簡単な形はリテラル表記で、/abc/のようにスラッシュで囲む方法です。これを使って文字列に対してmatchメソッドを呼び出すと、マッチした部分がMatchDataオブジェクトとして返ります。例えば"abc".match(/abc/)MatchDataを返し、nilが返るとマッチしません。

複数回のマッチを取得したい場合はscanメソッドを使用します。"abcabc".scan(/abc/)["abc", "abc"]という配列を返します。文字列を区切り文字で分割したいときはsplitメソッドが便利です。"a,b,c".split(/,/)["a", "b", "c"]を生成します。

さらに、~演算子を使うと、文字列が正規表現にマッチしたかどうかを簡潔に判定できます。"abc" =~ /abc/0(マッチ位置)を返し、マッチしない場合はnilになります。これにより条件分岐での使用がスムーズです。

regex = /abc/
"abc".match(regex)          # => #<MatchData "abc">
"abcabc".scan(regex)        # => ["abc", "abc"]
"a,b,c".split(/,/)          # => ["a", "b", "c"]
"abc" =~ /abc/              # => 0

高度な置換とキャプチャ

正規表現の強力な機能の一つにキャプチャグループがあります。(...)で囲んだ部分は後で参照でき、$1$2などでアクセスします。例えば"John Doe".match(/(\w+)\s+(\w+)/)$1 = "John"$2 = "Doe"となります。

置換時にキャプチャを利用することで、文字列の並び替えやフォーマット変更が簡単に行えます。"foo bar".gsub(/(\w+)\s+(\w+)/, '\2 \1')"bar foo"を返します。さらに、ブロックを渡すことで動的に置換値を計算できます。"foo123bar".gsub(/(\d+)/) { |m| m.to_i * 2 }"foo246bar"になります。

"John Doe".match(/(\w+)\s+(\w+)/)
# $1 => "John", $2 => "Doe"

"foo bar".gsub(/(\w+)\s+(\w+)/, '\2 \1')
# => "bar foo"

"foo123bar".gsub(/(\d+)/) { |m| m.to_i * 2 }
# => "foo246bar"

このようにRegexpmatchscansplit~演算子を組み合わせることで、テキスト処理の幅が大きく広がります。正規表現リテラルを活用し、キャプチャと高度な置換を駆使して、実務で頻繁に直面する文字列操作を効率化しましょう。

実践例とTips

Ruby実践で正規表現を使う代表的なケースとして、ログ解析やメールアドレス検証があります。ログファイルの行から日付を抽出する例を示します。

log_lines.each do |line|
  if line =~ /\[(\d{4})-(\d{2})-(\d{2})\]/
    year, month, day = $1, $2, $3
    # ここで日付を使った処理
  end
end

メールアドレスのバリデーションも正規表現で簡潔に実装できます。/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/iというリテラルを使えば、RFC 5322に準拠した簡易チェックが可能です。

さらに、複数行にわたるテキストから特定パターンを抜き出す際は、Regexp::MULTILINEフラグを付与してscanを使うと便利です。例えば、複数行にわたるコメントブロックを抽出する場合、/\/\*.*?\*\//mのように書きます。

最後に、正規表現を使う際のベストプラクティスとして、以下を意識しましょう。

  • リテラル表記は可読性が高いので、可能な限り使用する。
  • キャプチャグループは必要最低限に抑え、過剰なグループ化は避ける。
  • パフォーマンスが重要な場合は、Regexp::IGNORECASERegexp::EXTENDEDを適切に組み合わせる。
  • テストコードで正規表現の挙動を検証し、予期せぬマッチを防ぐ。

これらを踏まえてRuby実践で正規表現応用を行えば、コードの保守性と可読性を高めつつ、複雑な文字列処理をシンプルに実装できます。

この記事はAIによって作成されました。

コメント