Javaの正規表現とJavaScriptの正規表現の空白クラスは異なる

本日は軽いネタ。Java だろうが JavaScript だろうが、正規表現は拡張構文の違いはあるものの基本的には同じに扱える。と思いきや、Unicodeが入ってくるとだいぶ状況が違うようだ。

言語によってサロゲートペアの扱いが違うのは知っていたが、空白クラス(\s)の定義まで違うとは思わなかった。

例えば、Javaはこれ。ASCII範囲のものしか空白には含まれていない。XMLの空白([ \t\r\n])に比べるとやや範囲は広い。

また、いつの間にか以下のような見慣れない空白クラスも定義されている。

  • 水平方向の空白文字: [ \t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]
  • 垂直方向の空白文字: [\n\x0B\f\r\x85\u2028\u2029]

それに対し、JavaScriptUNICODE範囲の空白をすべて扱えるようだ(以前はASCII範囲だったはずような気がするのでES5で変わったのだろうか。定義書もざっと確認したが該当の記述を見つけられなかった)。

  • 空白文字: [ \f\n\r\t\v\u00A0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000] (参考:正規表現

しかし、この情報は古いのか、英語版のサイトを見に行くと以下のように書いてあり、少々内容が事なる。

  • 空白文字: [ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff] (参考:RegExp

使える正規表現が違うのは許容できるけれども、同じ名前で異なる範囲を表すというのは結構ワナだ。それはともかく実装により違うのだとすると予期せぬ動作にも繋がってしまうので、JavaScriptで空白クラスを使うのは避けたほうがいいのかもしれない。