正規表現チートシート
JavaScript 方言向けの検索可能な正規表現チートシート。文字クラス、ブラケット集合、量指定子、アンカー、先読み・後読み、グループ、フラグを例付きで掲載。
例付きの正規表現構文 41 項目。 トークン・説明・例を横断して絞り込み、必要な構文をそのままコピーできます。ブラウザと Node.js で使われる JavaScript(ECMAScript)方言に準拠しています。
条件に一致する構文はありません。
JavaScript 方言向けの検索可能な正規表現チートシート。文字クラス、ブラケット集合、量指定子、アンカー、先読み・後読み、グループ、フラグを例付きで掲載。
例付きの正規表現構文 41 項目。 トークン・説明・例を横断して絞り込み、必要な構文をそのままコピーできます。ブラウザと Node.js で使われる JavaScript(ECMAScript)方言に準拠しています。
条件に一致する構文はありません。
正規表現はもともと情報密度が高い記法です。^(?:\d{1,3}\.){3}\d{1,3}$ という 30 文字ほどのパターンに IPv4 バリデータ一式が収まっています。自分で書いたときは快適ですが、他人が書いたものを読むときは苦痛です。難しさの大半は概念ではなく、語彙が多く、簡潔で、中途半端に覚えやすいという点にあります。
このページはその語彙の逆引き表で、実際にパターンを組み立てる順序で整理してあります。1 文字に一致する記法、独自の文字集合の定義、「繰り返し」の表現、一致位置のアンカー、グループ化と選択、そしてエンジンの挙動を変えるフラグです。フィルタはトークン・説明・例を同時に検索するため、「最短」「boundary」「lookbehind」などを入力すれば、うろ覚えの行にすぐ辿り着けます。
正規表現は単一の言語ではありません。grep、PCRE、Python、Java、Go の RE2、JavaScript は共通の中核を持ちながら、細部で食い違います。ここに掲載しているものはすべて ECMAScript が定める JavaScript 方言を対象としています。ブラウザ、Node.js、そして大半のフロントエンドツールで動くのがこの方言だからです。
特に注意したい差異が三つあります。第一に、後読み (?<=...) と (?<!...) は現代の JavaScript エンジンでは利用できますが、Go の RE2 や古い Safari では使えないため、これに依存するパターンはどこでも移植できるわけではありません。第二に、JavaScript には x(拡張)フラグがないため、Python のようにパターンを複数行に分けてコメントを付けることはできません。長いパターンは通常、文字列断片を連結して組み立てます。第三に、JavaScript の \d と \w は既定で ASCII のみを対象とするため、u フラグ付きの \p{L} のような Unicode プロパティエスケープに切り替えない限り、\w はアクセント付き文字や CJK 文字に一致しません。
二つの習慣が、正規表現にまつわる苦労のほとんどを防いでくれます。一つ目は、意図してアンカーを付けることです。アンカーのないパターンは文字列内のどこかに一致を探します。テキストを走査する場合はそれで正しいのですが、検証する場合はほぼ常に不適切です。^ と $ を加えると「日付らしきものを含む」が「日付そのものである」に変わります。この違いが、検証系バグの相当な割合の背後にあります。
二つ目は、貪欲なワイルドカードよりも最短一致と否定文字クラスを選ぶことです。典型的な失敗は HTML 風のテキストに対する <.+> で、+ が貪欲なため行末近くの最後の > まで飲み込んでしまいます。<.+?>、さらに望ましくは <[^>]+> と書けば、タグ 1 個だけに一致します。否定クラス版はバックトラックが不要なぶん、速度面でも明確に有利です。
最後に、破滅的バックトラッキングに注意してください。(a+)+b のように量指定子を入れ子にすると、エンジンは「一致しない」と結論づける前に指数関数的な数の分割を試すことがあります。そのパターンがユーザー入力に触れる場合、検証処理がそのままサービス拒否の攻撃面になります。量指定子付きのグループがさらに量指定子を含んでいるなら書き直しましょう。多くの場合、文字クラス 1 つと量指定子 1 つで同じ仕事を線形時間でこなせます。そしてパターンが一、二行を超えて伸びてきたときは、正しい道具は正規表現ではなく本物のパーサーである、というのが正直な答えであることが多いのです。