RubyのRegexp.escapeを使って簡易的なワイルドカードによるマッチングをする

例えばログ出力をテストしたい時があり、時刻などは無視したい場合があるが、これを正規表現を使ってマッチングしようとすると正規表現において特別な意味を持つ文字のエスケープが大変で見にくいのでワイルドカードのような簡易的な表現にしたい。

actual = <<~EOS
  [INFO] [2024-07-04T10:00:00Z] message1
  [ERROR] [2024-07-04T10:00:01Z] #<StandardError: error>
  /path/to/file1:10:in `initialize'
  /path/to/file2:3:in `hoge'
  /path/to/file3:5:in `foo'
  [INFO] [2024-07-04T10:00:02Z] message3
EOS

expected = Regexp.new(<<~EOS, Regexp::MULTILINE)
  \\[INFO\\] \\[.+\\] message1
  \\[ERROR\\] \\[.+\\] #<StandardError: error>
  .+
  \\[INFO\\] \\[.+\\] message3
EOS

expect(actual).to match(expected)

ここで Ruby には Regexp.escape1 という正規表現において特別な意味を持つ文字をエスケープしてくれるメソッドがあり、これを使うとエスケープしなくて済む。そしてエスケープするときに自身で定義したワイルドカード文字列(ここでは%ワイルドカードとする)を正規表現に置き換えればワイルドカードによる簡易的なマッチングできるようなる。

actual = <<~EOS
  [INFO] [2024-07-04T10:00:00Z] message1
  [ERROR] [2024-07-04T10:00:01Z] #<StandardError: error>
  /path/to/file1:10:in `initialize'
  /path/to/file2:3:in `hoge'
  /path/to/file3:5:in `foo'
  [INFO] [2024-07-04T10:00:02Z] message3
EOS

expected = Regexp.new(Regexp.escape(<<~EOS).gsub('%','.+'), Regexp::MULTILINE)
  [INFO] [%] message1
  [ERROR] [%] #<StandardError: error>
  %
  [INFO] [%] message3
EOS

expect(actual).to match(expected)

環境