JavaScript: Chrome V8なら正規表現で後読み(look behind)がフル機能で使える

以下は記事公開時点の情報です。

Chrome V8だと正規表現の後読みが、動くぞ!

きっかけは、regex101.comでJavaScriptの正規表現をチェック中に、後読み(look behind)がエラーを起こしていないことに気づいたことでした(実行環境はChrome 70.0.3538.67)。


regex101.comより

あれ?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


regex101.comより

  • Firefox


regex101.comより

赤々とエラーが灯っています。なるほど動かん。Mac環境につき、IEやEdgeは試していません。

Chrome V8の正規表現では後読みで「量指定子」が使える!

驚くのはここからです。少し試してみると、*と並んで最も凶悪な+量指定子が後読みの中であっさり使えたのです。


regex101.comより

?も、{N}も、否定後読みも、量指定子がことごとく通るではありませんか。

後読みの中で量指定子を使える正規表現ライブラリといえば、私の知る限りでは.NET Frameworkぐらいしかありませんでした↓。PerlやRubyの正規表現でもできない「後読み+量指定子」を使える正規表現が他にもあったとは😳。


regexstorm.netより

不明を恥じることこの上ありません。V8凄い💪。やればできるじゃん。

「後読み+量指定子(特に長さ不定の量指定子)」が非常に効率が悪いことは承知しています。凶悪な*だの+だのを後読みの中で連発するとパフォーマンスがどかんと落ちる可能性があります。しかし少なくとも私にとって「後読み+量指定子」はどうしてもないと困る表現なのです。私が使うのはせいぜい?{N,M}といったかわいらしい量指定子ですが。

ここは想像ですが、おそらくRubyやPCRE系の正規表現ライブラリでは、効率の悪いこの書き方を自主規制してるのではないかと思いました。

もちろんWebやモバイルアプリの開発者にとっては、特定のブラウザでしか使えない正規表現機能などほとんど意味がないと思いますし、うかつに取り入れてセキュリティ問題を引き起こさないよう注意も必要でしょう。でも私のユースケースではとっても嬉しい機能です😭。

Chrome V8正規表現の他の機能/まだない機能

冒頭の記事で引用されていた以下のスライドで、V8の正規表現機能の対応を含む今後のES2018の予定が公式に説明されていました。スライドは今年3月のものですが、既に実現されているものや、これからのものがあります。


slidr.ioより

  • 正規表現のsオプション(/正規表現/sと指定)を使うと、.改行でもマッチするようになります。
    • これは現在のChromeで動きます(regex101)。
  • ()によるキャプチャは前からできてたようですが(regex101.com)、名前付きキャプチャが使えるようになるそうです。
  • Unicode文字クラスも対応するそうです。
    • 現在のChromeでは、[\p{なんちゃら}]はピクリとも動きません(regex101.com)。Canary版でもだめでした😇。

以上は現時点のChromeで確認したものなので、今後変わると思われます。

個人的には、sオプションのように正規表現の外で挙動を変えるオプションは使いたくないと思っています(大文字小文字を区別しないiなども使っていません)。.のような雑なメタ文字を使うぐらいなら、hello[\n|\s|\S]worldのようにスペースと改行の両方にマッチする正規表現を明示的に書く方を選びます。

また、普通のキャプチャがあれば名前付きキャプチャはあまり使わなさそうですが、Unicode文字クラスはぜひとも期待したいところです😍。Rubyに負けないくらいUnicode文字クラスを手厚くサポートして欲しいと願っています✨。

関連記事

Ruby正規表現の後読みでは長さ不定の量指定子は原則使えない

はじめての正規表現とベストプラクティス#1: 基本となる8つの正規表現

[連載:正規表現] Unicode文字プロパティについて(1)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ