以下は記事公開時点の情報です。
Chrome V8だと正規表現の後読みが、動くぞ!
きっかけは、regex101.comでJavaScriptの正規表現をチェック中に、後読み(look behind)がエラーを起こしていないことに気づいたことでした(実行環境はChrome 70.0.3538.67)。
あれ?JavaScriptの正規表現といえば後読みがまったく使えないんじゃなかったっけ?
その場はスルーしていましたが、それからしばらくして今度は以下の記事を見かけました。
Lookbehinds will work the same way but for patterns before the matching pattern (lookaheads consider the patters after the matching part) and are already supported in Chrome today. They will also be available as positive lookbehind x(?<=y) and the negative lookbehind x(?<!y).
同記事より(一部強調)
れれ、Chromeだと動く...?
もう少し探すと今度はこんな記事が。
記事は2015年11月20日に公開されていました。3年も前にChrome V8のJavaScriptの正規表現で後読みが使えるようになっていたとはまったく気づきませんでした。今になって気づくとはお恥ずかしい限りです😓。
それより前にさまざまな正規表現ライブラリの先読み/後読みを調べたとき、JavaScriptで後読みがまったく利用できないことを知って当分無理だと深く絶望し、JavaScriptで正規表現など使うまいと誓って以来JavaScriptの正規表現を追っていなかったのが原因でした😇。
他のブラウザ
同じパターンを別のブラウザで試してみました。
- Safari
- Firefox
赤々とエラーが灯っています。なるほど動かん。Mac環境につき、IEやEdgeは試していません。
Chrome V8の正規表現では後読みで「量指定子」が使える!
驚くのはここからです。少し試してみると、*
と並んで最も凶悪な+
量指定子が後読みの中であっさり使えたのです。
?
も、{N}
も、否定後読みも、量指定子がことごとく通るではありませんか。
後読みの中で量指定子を使える正規表現ライブラリといえば、私の知る限りでは.NET Frameworkぐらいしかありませんでした↓。PerlやRubyの正規表現でもできない「後読み+量指定子」を使える正規表現が他にもあったとは😳。
不明を恥じることこの上ありません。V8凄い💪。やればできるじゃん。
「後読み+量指定子(特に長さ不定の量指定子)」が非常に効率が悪いことは承知しています。凶悪な*
だの+
だのを後読みの中で連発するとパフォーマンスがどかんと落ちる可能性があります。しかし少なくとも私にとって「後読み+量指定子」はどうしてもないと困る表現なのです。私が使うのはせいぜい?
や{N,M}
といったかわいらしい量指定子ですが。
ここは想像ですが、おそらくRubyやPCRE系の正規表現ライブラリでは、効率の悪いこの書き方を自主規制してるのではないかと思いました。
もちろんWebやモバイルアプリの開発者にとっては、特定のブラウザでしか使えない正規表現機能などほとんど意味がないと思いますし、うかつに取り入れてセキュリティ問題を引き起こさないよう注意も必要でしょう。でも私のユースケースではとっても嬉しい機能です😭。
Chrome V8正規表現の他の機能/まだない機能
冒頭の記事で引用されていた以下のスライドで、V8の正規表現機能の対応を含む今後のES2018の予定が公式に説明されていました。スライドは今年3月のものですが、既に実現されているものや、これからのものがあります。
- 正規表現の
s
オプション(/正規表現/s
と指定)を使うと、.
が改行でもマッチするようになります。- これは現在のChromeで動きます(regex101)。
()
によるキャプチャは前からできてたようですが(regex101.com)、名前付きキャプチャが使えるようになるそうです。- これも現在のChromeで動きます(https://regex101.com)。
- Unicode文字クラスも対応するそうです。
- 現在のChromeでは、
[\p{なんちゃら}]
はピクリとも動きません(regex101.com)。Canary版でもだめでした😇。
- 現在のChromeでは、
以上は現時点のChromeで確認したものなので、今後変わると思われます。
個人的には、s
オプションのように正規表現の外で挙動を変えるオプションは使いたくないと思っています(大文字小文字を区別しないi
なども使っていません)。.
のような雑なメタ文字を使うぐらいなら、hello[\n|\s|\S]world
のようにスペースと改行の両方にマッチする正規表現を明示的に書く方を選びます。
また、普通のキャプチャがあれば名前付きキャプチャはあまり使わなさそうですが、Unicode文字クラスはぜひとも期待したいところです😍。Rubyに負けないくらいUnicode文字クラスを手厚くサポートして欲しいと願っています✨。
- 参考: Unicode Character Categories -- Unicode文字クラスの確認に便利です。