Ruby reモジュール:複雑な正規表現をゼロにする


複雑な正規表現は構築しにくく、読みにくい.RubyのReモジュールは、簡単な式で複雑な正規表現を構築するのに役立ちます.たとえば、次の照合日の正規表現を考慮します.
/\A((?:19|20)[0-9]{2})[\- \/.](0[1-9]|1[012])[\- \/.](0[1-9]|[12][0-9]|3[01])\z/

Reを使用すると、正規表現は短くて読みやすい表現に基づいて構築されます.たとえば、次のようになります.
require 're'

include Re

delim                = re.any("- /.")
century_prefix       = re("19") | re("20")
under_ten            = re("0") + re.any("1-9")
ten_to_twelve        = re("1") + re.any("012")
ten_and_under_thirty = re.any("12") + re.any("0-9")
thirties             = re("3") + re.any("01")

year = (century_prefix + re.digit.repeat(2)).capture(:year)
month = (under_ten | ten_to_twelve).capture(:month)
day = (under_ten | ten_and_under_thirty | thirties).capture(:day)

date = (year + delim + month + delim + day).all

コード量は増加したが,各部分が短く検証も容易である.また、取得されたセクションは、対応する変数名でアクセスできます.
result = date.match("2009-01-23")
result[:year]      # => "2009"
result[:month]     # => "01"
result[:day]       # => "23"

Reで正規表現を作成するのは遅いので、正規表現を作成して多重化することをお勧めします.マッチングすると,性能は原生の正規表現に近い.(Re::Resultを呼び出して作成し、マッチング結果を返してわずかなパフォーマンスに影響を与える追加の方法.)究極のパフォーマンスを追求する必要がある場合は、Reを使用して正規表現を構築し、元のRuby Regexpを抽出してマッチングすることができます.これでは、オリジナルの正規表現を使うのと同じ性能になります.
たとえば、電話番号に一致する正規表現を作成します.
PHONE_RE = re.digit.repeat(3).capture(:area) +
               re("-") +
               re.digit.repeat(3).capture(:exchange) +
               re("-") +
               re.digit.repeat(4)).capture(:subscriber)

次に、元の正規オブジェクトを抽出し、それを直接使用してマッチングします.
PHONE_REGEXP = PHONE_RE.regexp

if PHONE_REGEXP =~ string
  # blah blah blah
end

関連リンク
  • プロジェクトホームページ
  • 文書
  • Gem
  • ダウンロード
  • Bug
  • 継続的統合
  • 許可する
    Copyright 2009 by Jim Weirich. Under MIT open source license.
    SegmentFaultのコンパイル