MiServe DevTools

あなたのステッカー

ツールをここにピン留めできます。このブラウザに保存されます。

正規表現テスター(JavaScript・Go RE2 対応)

正規表現を JavaScript エンジンまたは Go の RE2 エンジンでテキストに適用し、すべてのマッチ、キャプチャグループ、置換結果を確認できます。

フラグ

テキスト中のマッチ

両エンジンの構文早見表
記法意味JavaScriptGo (RE2)
. 改行以外の任意の 1 文字。s フラグを付けると改行にもマッチします。 対応 対応
\d \w \s 数字、単語構成文字、空白文字。大文字の \D、\W、\S はそれぞれその逆にマッチします。 対応 対応
[abc] [^abc] [a-z] 集合に含まれる 1 文字、集合に含まれない 1 文字、範囲内の 1 文字。 対応 対応
^ $ テキストの先頭と末尾。m フラグを付けると各行の先頭と末尾。 対応 対応
\b \B 単語境界と、単語境界ではない位置。 対応 対応
* + ? {2,5} 0 回以上、1 回以上、0 回または 1 回、2 回以上 5 回以下。いずれもできるだけ多くマッチします。 対応 対応
*? +? ?? {2,5}? 同じ量指定子の、できるだけ少なくマッチする形。 対応 対応
(…) (?:…) キャプチャグループと、グループ化だけを行うグループ。 対応 対応
(?<name>…) 名前付きキャプチャグループ。Go ではバージョン 1.22 からこの形式を使えます。(?P<name>…) はすべてのバージョンで使えます。 対応 対応
a|b a または b。 対応 対応
\p{L} \p{Lu} Unicode プロパティ:任意の文字、任意の大文字。JavaScript では u フラグが必要です。 対応 対応
(?i) (?s) (?m) パターンの中に書くフラグ。JavaScript ではフラグをパターンの外側で指定します。 非対応 対応
\A \z m フラグにかかわらず、テキスト全体の先頭と末尾。 非対応 対応
[[:alpha:]] 文字集合の中で使う POSIX 文字クラス。 非対応 対応
(?=…) (?!…) 先読み:後に続く部分がマッチする(またはマッチしない)ことを、文字を消費せずに確認します。 対応 非対応
(?<=…) (?<!…) 後読み:前にある部分がマッチする(またはマッチしない)ことを確認します。 対応 非対応
\1 \k<name> 後方参照:前のグループがマッチしたのと同じテキスト。 対応 非対応

WebAssembly を使ってブラウザ内で動作します。貼り付けた内容はアップロードされません。

このツールについて

系統の異なる 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 モジュールとして実行されます。このツールがパターンやテキストを含むネットワークリクエストを送ることはなく、サイトのセキュリティポリシーにより、ほかのホストへのリクエストはブロックされます。

テキストのほかのツール