2016/09/29

改行文字やタブなどを含む複数行を正規表現でマッチさせる

DBMSのログを、JavaScriptの正規表現を使って整形して表示するということをしていた。
< 2016-09-27 11:48:17.282 JST >STATEMENT:select *\r\n\tfrom test\r\n\twhere id = 1;\n」を「/(\d{4}-\d{2}-\d{2}\s+\d{1,2}:\d{2}:\d{2}\.\d{3}\s\w{3,5}).+>(.+?):\s+(.*)/」の正規表現で、次のように分割したかった。

  • 2016-09-27 11:48:17.282 JST
  • STATEMENT
  • select *\r\n\tfrom test\r\n\twhere id = 1;\n

しかし、3つ目を「(.*)」でマッチングさせているのに「select *」しか取得できない。
なぜか改行やタブが入ると取得できず、ちょっとハマりかけた。

改行やタブを含む行をヒットさせる


結論からいうと、ピリオド(.)の意味を間違えて理解していた。ピリオドは「任意の1文字」だと思っていたのだが、正確には「改行文字を除く任意の1文字」だった。

そこで以下のメタキャラクタを指定すると、この問題が解決できた。

  • \s … スペース、タブなどの任意の空文字に一致する(\f\n\r\t\vと同じ)
  • \S … 任意の空文字以外に一致する(^\f\n\r\t\vと同じ、\sの反対)

(.*) の部分を [\s\S*] に変更するして、「/(\d{4}-\d{2}-\d{2}\s+\d{1,2}:\d{2}:\d{2}\.\d{3}\s\w{3,5}).+>(.+?):\s+(\s\S*)/」のようにすることで、ちゃんと改行やタブなどの空文字を含む複数行をヒットさせることができた。


ちなみにRubyだと「(.*)」でも改行文字も含むことができたんだけどなぁ…。



参考サイト




以上

written by @bc_rikko

2 件のコメント :

  1. 同じような状況でハマりました(笑)。
    この記事のおかげで解決できました、ありがとうございます。

    返信削除
    返信
    1. コメントありがとうございます!
      お役に立てたようでなによりですw

      削除