あなたのステッカー
ツールをここにピン留めできます。このブラウザに保存されます。
ツールをピン留めすると、そのステッカーがここに並びます。
このツールについて
系統の異なる 2 つのエンジン
正規表現エンジンは大きく 2 つの系統に分かれます。PCRE や、JavaScript、Python、Java、.NET の標準エンジンといったバックトラック型のエンジンは、パターンの経路を 1 つずつ試し、失敗すると戻ってやり直します。この設計のおかげで先読み、後読み、後方参照が使えます。RE2 や Go の regexp パッケージといったオートマトン型のエンジンは、考えられるすべての経路を同時にたどるので、実行時間はテキストの長さに対して線形に増えます。その代わり、先読み・後読みと後方参照は使えません。
このツールの JavaScript エンジンは、お使いのブラウザ自身の RegExp です。Go エンジンは Go の標準パッケージ regexp を WebAssembly にコンパイルしたもので、ここでパターンを実行するコードは Go のプログラムで実行されるコードと同じです。Go が受け付ける構文は RE2 の構文です。
結果の読み方
各マッチはテキスト上で枠とハイライトで示されます。隣り合うマッチを区別できるよう、2 色を交互に使います。x* が 2 文字の間に見つけるような空のマッチは、細い縦線で表示されます。表には各マッチの開始位置と終了位置、各キャプチャグループのテキストが並びます。マッチに関与しなかったグループは「未マッチ」と表示され、空文字列にマッチしたグループとは区別されます。
位置は 0 から数えた UTF-16 コードユニット単位で、終了位置はその位置を含みません。JavaScript の String.prototype.slice にそのまま渡せる数値です。Go 自体は UTF-8 テキストのバイトオフセットを返しますが、ツールが変換するので、どちらのエンジンでも同じ数値が表示されます。
JavaScript では、g フラグのないパターンは最初のマッチだけを見つけ、最初のマッチだけを置換します。Go エンジンは、FindAllStringSubmatchIndex や ReplaceAllString と同じく、常にすべてのマッチを返します。
破滅的バックトラック
バックトラック型のエンジンでは、量指定子が入れ子になっていたり重なっていたりすると、指数関数的な時間がかかることがあります。典型例は、a が長く続いたあとに別の文字が来るテキストに (a+)+$ を適用する場合です。エンジンは失敗と判断するまでに、その連続部分を内側と外側の量指定子に振り分けるあらゆる方法を試します。サーバー上では、これは ReDoS と呼ばれるサービス拒否攻撃のリスクになります。
このツールは JavaScript のパターンをバックグラウンドワーカーで実行し、1.5 秒でワーカーを停止します。そのためページは固まらず、何が起きたかを表示できます。同じパターンを Go エンジンで試せば、遅さの原因がバックトラックかどうかをすぐに確かめられます。Go はテキストの長さに対して線形の実行時間を保証しているからです。
よくある質問
JavaScript では動くパターンが Go で失敗するのはなぜですか?
よくある原因は先読み、後読み、後方参照です。RE2 は線形の実行時間を保証するため、これらを備えていません。フラグもよくある原因です。Go にはパターンの外側で指定するフラグがないため、大文字と小文字を区別しないマッチはパターンの先頭に (?i) と書きます。
置換文字列の書き方は JavaScript と Go でどう違いますか?
最初のグループはどちらも $1 です。名前付きグループは JavaScript では $<name>、Go では ${name} です。Go では $1x が 1x という名前のグループを意味するので、参照の直後に英字、数字、アンダースコアが続く場合は ${1}x と書きます。
PCRE、Python、Java のパターンもテストできますか?
このページで動くのは JavaScript と Go のエンジンだけです。日常的に使う構文はどの方言でも共通なので、単純なパターンなら JavaScript エンジンで十分に近い結果が得られます。ただし、強欲な量指定子、アトミックグループ、再帰といった機能は、ここではどちらのエンジンでも使えません。
テストしたテキストはサーバーに送信されますか?
いいえ。どちらのエンジンもブラウザ内で動作します。JavaScript はバックグラウンドワーカーで、Go は WebAssembly モジュールとして実行されます。このツールがパターンやテキストを含むネットワークリクエストを送ることはなく、サイトのセキュリティポリシーにより、ほかのホストへのリクエストはブロックされます。