正規表現構文 横断検索
JavaScript / Python / Go / Java / PCRE の正規表現構文を横断比較
abc文字列 "abc" に完全一致
abc文字列 "abc" に完全一致
abc文字列 "abc" に完全一致
abc文字列 "abc" に完全一致
abc文字列 "abc" に完全一致
.改行以外の任意の1文字にマッチ
* sフラグで改行にもマッチ
.改行以外の任意の1文字にマッチ
* re.DOTALL で改行にもマッチ
.改行以外の任意の1文字にマッチ
* (?s) フラグで改行にもマッチ
.改行以外の任意の1文字にマッチ
* Pattern.DOTALL で改行にもマッチ
.改行以外の任意の1文字にマッチ
* s修飾子で改行にもマッチ
\. \* \+バックスラッシュで特殊文字をエスケープ
\. \* \+バックスラッシュでエスケープ
* raw文字列 r"\." の使用を推奨
\. \* \+バックスラッシュでエスケープ
* バッククォート `\.` で raw文字列
\. \* \+バックスラッシュでエスケープ
* Java文字列内では \\\\ が必要
\. \* \+バックスラッシュでエスケープ
比較メモ: Java は文字列リテラル内でバックスラッシュを二重にする必要があるため、"\\d" のようになる
cat|dog"cat" または "dog" にマッチ
cat|dog"cat" または "dog" にマッチ
cat|dog"cat" または "dog" にマッチ
cat|dog"cat" または "dog" にマッチ
cat|dog"cat" または "dog" にマッチ
[abc]a, b, c のいずれか1文字にマッチ
[abc]a, b, c のいずれか1文字にマッチ
[abc]a, b, c のいずれか1文字にマッチ
[abc]a, b, c のいずれか1文字にマッチ
[abc]a, b, c のいずれか1文字にマッチ
[^abc]a, b, c 以外の任意の1文字にマッチ
[^abc]a, b, c 以外の任意の1文字にマッチ
[^abc]a, b, c 以外の任意の1文字にマッチ
[^abc]a, b, c 以外の任意の1文字にマッチ
[^abc]a, b, c 以外の任意の1文字にマッチ
[a-z0-9]小文字アルファベットまたは数字にマッチ
[a-z0-9]小文字アルファベットまたは数字にマッチ
[a-z0-9]小文字アルファベットまたは数字にマッチ
[a-z0-9]小文字アルファベットまたは数字にマッチ
[a-z0-9]小文字アルファベットまたは数字にマッチ
\d[0-9] と同等
\d[0-9] と同等
* Unicode数字にもマッチ(re.ASCII で制限可)
\d[0-9] と同等
* RE2エンジン。ASCII数字のみ
\d[0-9] と同等
* デフォルトでASCII数字のみ
\d[0-9] と同等
* ロケール依存の場合あり
比較メモ: Python の \d はデフォルトで全角数字などUnicode数字にもマッチする。ASCII限定にするには re.ASCII フラグを使用
\w[a-zA-Z0-9_] と同等
* uフラグでUnicode対応
\w[a-zA-Z0-9_] と同等
* デフォルトでUnicode対応。re.ASCII で制限可
\w[a-zA-Z0-9_] と同等
* ASCII文字のみ
\w[a-zA-Z0-9_] と同等
* Pattern.UNICODE_CHARACTER_CLASS でUnicode対応
\w[a-zA-Z0-9_] と同等
* ロケール依存の場合あり
\sスペース・タブ・改行等の空白文字にマッチ
\sスペース・タブ・改行等にマッチ
* Unicode空白文字も含む
\sスペース・タブ・改行等にマッチ
\sスペース・タブ・改行等にマッチ
\sスペース・タブ・改行等にマッチ
\D \W \S\d, \w, \s の否定(非数字・非単語文字・非空白)
\D \W \S\d, \w, \s の否定
\D \W \S\d, \w, \s の否定
\D \W \S\d, \w, \s の否定
\D \W \S\d, \w, \s の否定
JavaScript は POSIX 文字クラス非対応
Python は POSIX 文字クラス非対応
[a-zA-Z] 等で代替
[[:alpha:]]POSIX文字クラスを [] 内で使用
* [[:digit:]], [[:alnum:]] 等
\p{Alpha}POSIX文字クラスを \p{} で使用
* \p{Digit}, \p{Alnum} 等
[[:alpha:]]POSIX文字クラスを [] 内で使用
* [[:digit:]], [[:alnum:]] 等
比較メモ: POSIX文字クラスは Go と PCRE が [[:class:]] 形式、Java が \p{Class} 形式。JS/Python は非対応
a*"a" の0回以上の繰り返し(貪欲)
a*"a" の0回以上の繰り返し(貪欲)
a*"a" の0回以上の繰り返し(貪欲)
a*"a" の0回以上の繰り返し(貪欲)
a*"a" の0回以上の繰り返し(貪欲)
a+"a" の1回以上の繰り返し(貪欲)
a+"a" の1回以上の繰り返し(貪欲)
a+"a" の1回以上の繰り返し(貪欲)
a+"a" の1回以上の繰り返し(貪欲)
a+"a" の1回以上の繰り返し(貪欲)
a?"a" が0回または1回(省略可能)
a?"a" が0回または1回
a?"a" が0回または1回
a?"a" が0回または1回
a?"a" が0回または1回
a{3}"a" のちょうど3回の繰り返し
a{3}"a" のちょうど3回の繰り返し
a{3}"a" のちょうど3回の繰り返し
a{3}"a" のちょうど3回の繰り返し
a{3}"a" のちょうど3回の繰り返し
a{2,5}"a" の2回以上5回以下の繰り返し
a{2,5}"a" の2回以上5回以下の繰り返し
a{2,5}"a" の2回以上5回以下の繰り返し
a{2,5}"a" の2回以上5回以下の繰り返し
a{2,5}"a" の2回以上5回以下の繰り返し
a*? a+? a??? を付けて非貪欲(最短一致)にする
a*? a+? a??? を付けて非貪欲にする
a*? a+? a??? を付けて非貪欲にする
a*? a+? a??? を付けて非貪欲にする
a*? a+? a??? を付けて非貪欲にする
* U修飾子でデフォルトを非貪欲に変更可
比較メモ: PCRE では U修飾子を使うとデフォルトの貪欲/非貪欲を反転できる
ES2024 まで非対応
アトミックグループで代替可能(提案段階)
Python の re モジュールは非対応
regex モジュール(pip install regex)で対応
RE2 エンジンは独占的量指定子非対応
a*+ a++ a?++ を付けてバックトラックを禁止
* パフォーマンス最適化に有用
a*+ a++ a?++ を付けてバックトラックを禁止
比較メモ: 独占的量指定子は Java と PCRE のみ対応。パターンマッチの効率化に使われる
^行の先頭にマッチ
* mフラグで各行の先頭にマッチ
^行の先頭にマッチ
* re.MULTILINE で各行の先頭にマッチ
^行の先頭にマッチ
* (?m) で各行の先頭にマッチ
^行の先頭にマッチ
* Pattern.MULTILINE で各行の先頭にマッチ
^行の先頭にマッチ
* m修飾子で各行の先頭にマッチ
$行の末尾にマッチ
* mフラグで各行の末尾にマッチ
$行の末尾にマッチ
* re.MULTILINE で各行の末尾にマッチ
$行の末尾にマッチ
* (?m) で各行の末尾にマッチ
$行の末尾にマッチ
* Pattern.MULTILINE で各行の末尾にマッチ
$行の末尾にマッチ
* m修飾子で各行の末尾にマッチ
\b単語の境界にマッチ
* \B で非境界にマッチ
\b単語の境界にマッチ
* raw文字列 r"\b" の使用を推奨
\b単語の境界にマッチ
\b単語の境界にマッチ
\b単語の境界にマッチ
JavaScript に \A はない
^をmフラグなしで使用
\A文字列の先頭にマッチ(MULTILINE の影響を受けない)
\A文字列の先頭にマッチ
\A文字列の先頭にマッチ
\A文字列の先頭にマッチ
比較メモ: JavaScript は \A をサポートしていない。^ をmフラグなしで使うことで同等の動作になる
JavaScript に \z / \Z はない
$をmフラグなしで使用
\Z文字列の末尾にマッチ
* Python は \z ではなく \Z を使用
\z文字列の末尾にマッチ
\z文字列の末尾にマッチ
* \Z は末尾の改行の前にもマッチ
\z文字列の末尾にマッチ
* \Z は末尾の改行の前にもマッチ
比較メモ: Python は \Z(大文字)を使い、Java/PCRE は \z(小文字)が厳密な末尾マッチ。Java/PCRE の \Z は末尾改行の前にもマッチする
(abc)括弧内のパターンをグループ化してキャプチャ
(abc)括弧内のパターンをグループ化してキャプチャ
(abc)括弧内のパターンをグループ化してキャプチャ
(abc)括弧内のパターンをグループ化してキャプチャ
(abc)括弧内のパターンをグループ化してキャプチャ
(?:abc)グループ化のみ(キャプチャしない)
(?:abc)グループ化のみ(キャプチャしない)
(?:abc)グループ化のみ(キャプチャしない)
(?:abc)グループ化のみ(キャプチャしない)
(?:abc)グループ化のみ(キャプチャしない)
(?<name>abc)ES2018以降。groups.name でアクセス
(?P<name>abc)Python は (?P<name>) 形式
* group("name") でアクセス
(?P<name>abc)Go は (?P<name>) 形式
* SubexpNames() で名前を取得
(?<name>abc)Java 7以降。group("name") でアクセス
(?P<name>abc)
(?<name>abc)
(?'name'abc)PCRE は3つの構文すべて対応
比較メモ: 名前付きキャプチャの構文は言語間で異なる。Python/Go は (?P<name>) 形式、JS/Java は (?<name>) 形式。PCRE は両方対応
\11番目のキャプチャグループを参照
\11番目のキャプチャグループを参照
RE2 エンジンは後方参照に非対応
線形時間保証のため意図的に非対応
\11番目のキャプチャグループを参照
\11番目のキャプチャグループを参照
比較メモ: Go の RE2 エンジンは後方参照を意図的にサポートしていない。計算量が指数関数的に増大する可能性があるため
\k<name>ES2018以降。名前付きグループの参照
(?P=name)Python は (?P=name) 形式
RE2 エンジンは後方参照に非対応
\k<name>Java 7以降
(?P=name)
\k<name>
\k'name'PCRE は複数の構文に対応
比較メモ: 名前付き後方参照も言語間で構文が異なる。Python は (?P=name)、JS/Java は \k<name>
ES2024 で提案中
独占的量指定子も未対応
re モジュールは非対応
regex モジュール(pip install regex)で対応
RE2 エンジンは原子グループ非対応
(?>abc)原子グループ。一度マッチしたらバックトラックしない
(?>abc)原子グループ。パフォーマンス最適化に有用
比較メモ: 原子グループは Java と PCRE のみ対応。パターンマッチの効率を向上させるが、使い方を誤ると期待外のマッチ失敗を起こす
(?=abc)直後に "abc" が続く位置にマッチ
(?=abc)直後に "abc" が続く位置にマッチ
RE2 エンジンは先読み・後読み非対応
正規表現を分割するか、別の方法で代替
(?=abc)直後に "abc" が続く位置にマッチ
(?=abc)直後に "abc" が続く位置にマッチ
比較メモ: Go の RE2 エンジンは先読み・後読みを一切サポートしていない。線形時間保証のため
(?!abc)直後に "abc" が続かない位置にマッチ
(?!abc)直後に "abc" が続かない位置にマッチ
RE2 エンジンは先読み非対応
(?!abc)直後に "abc" が続かない位置にマッチ
(?!abc)直後に "abc" が続かない位置にマッチ
(?<=abc)ES2018以降。直前に "abc" がある位置にマッチ
* 一部の古いブラウザでは非対応
(?<=abc)直前に "abc" がある位置にマッチ
* 固定長パターンのみ対応
RE2 エンジンは後読み非対応
(?<=abc)直前に "abc" がある位置にマッチ
* 固定長パターンが推奨。可変長は制限あり
(?<=abc)直前に "abc" がある位置にマッチ
* 可変長の後読みも一部対応
比較メモ: JS は ES2018 から対応。Go は非対応。Python は固定長パターンのみ。PCRE は最も柔軟に可変長後読みをサポート
(?<!abc)ES2018以降。直前に "abc" がない位置にマッチ
(?<!abc)直前に "abc" がない位置にマッチ
* 固定長パターンのみ対応
RE2 エンジンは後読み非対応
(?<!abc)直前に "abc" がない位置にマッチ
(?<!abc)直前に "abc" がない位置にマッチ
\p{L}Unicode文字(Letter)にマッチ
* u または v フラグが必須
\p{L}Unicode文字にマッチ
* regex モジュールが必要。re モジュールは非対応
\p{L}Unicode文字にマッチ
* RE2 は Unicode プロパティ対応
\p{L}Unicode文字にマッチ
* \p{IsL} でも可。Java は広範な Unicode プロパティをサポート
\p{L}Unicode文字にマッチ
* PCRE2 は広範な Unicode プロパティをサポート
比較メモ: Python の標準 re モジュールは \p{} 非対応。regex モジュール(pip install regex)を使用する必要がある
\p{Script=Hiragana}ひらがなにマッチ
* u または v フラグが必須
re モジュールは非対応
regex モジュールで \p{Hiragana} が使用可能
\p{Hiragana}ひらがなにマッチ
* \p{Katakana}, \p{Han} も使用可能
\p{IsHiragana}ひらがなにマッチ
* \p{IsKatakana}, \p{IsHan} も可
\p{Hiragana}ひらがなにマッチ
* \p{Katakana}, \p{Han} も使用可能
比較メモ: 日本語文字のマッチは各言語で構文が異なる。Java は Is プレフィックスが必要
\u{1F600}
\u3042\u{} で任意のコードポイント(uフラグ必須)
* \uXXXX は BMP のみ
\u3042
\U0001F600\u で4桁、\U で8桁のコードポイント
\x{3042}\x{} でコードポイントを指定
\u3042
\x{1F600}\u で4桁。\x{} は Java 7以降
\x{3042}\x{} でコードポイントを指定
比較メモ: コードポイント指定の構文は言語間で異なる。サロゲートペア対応にも注意が必要
\p{N} \p{P}数字(N)・句読点(P)等のカテゴリ
* u/v フラグ必須
re モジュールは非対応
regex モジュールで対応
\p{N} \p{P}数字(N)・句読点(P)等のカテゴリ
\p{N} \p{P}数字(N)・句読点(P)等のカテゴリ
* \p{IsN} 形式でも可
\p{N} \p{P}数字(N)・句読点(P)等のカテゴリ
JavaScript は \X 非対応
v フラグの \p{RGI_Emoji} で一部対応
re モジュールは非対応
regex モジュールで \X が使用可能
RE2 エンジンは \X 非対応
Java は \X 非対応
\b{g} で書記素境界を検出可(Java 9以降)
\X書記素クラスタ(絵文字含む複合文字)にマッチ
* PCRE2 でフルサポート
比較メモ: 書記素クラスタのマッチは PCRE のみが \X でネイティブ対応。他の言語では専用ライブラリが必要
/pattern/ii フラグで大文字小文字を無視
re.IGNORECASE
(?i)re.I を flags 引数に指定。またはインライン (?i)
(?i)インラインフラグ (?i) をパターン先頭に付与
Pattern.CASE_INSENSITIVE
(?i)Pattern.compile("pattern", Pattern.CASE_INSENSITIVE)
/pattern/ii 修飾子で大文字小文字を無視
/pattern/mm フラグで ^ と $ が各行の先頭・末尾にマッチ
re.MULTILINE
(?m)re.M を flags 引数に指定
(?m)インラインフラグ (?m)
Pattern.MULTILINE
(?m)Pattern.compile("pattern", Pattern.MULTILINE)
/pattern/mm 修飾子
/pattern/ss フラグで . が改行文字にもマッチ
* ES2018 以降
re.DOTALL
(?s)re.S を flags 引数に指定
(?s)インラインフラグ (?s)
Pattern.DOTALL
(?s)Pattern.compile("pattern", Pattern.DOTALL)
/pattern/ss 修飾子
比較メモ: JavaScript の s フラグは ES2018 で追加された比較的新しい機能
/pattern/u
/pattern/vu: Unicode対応。v: Unicode Sets(ES2024)
* v は u の上位互換
re.UNICODEPython 3 ではデフォルトで Unicode 対応
* re.ASCII で ASCII 限定に切り替え可
Go はデフォルトで UTF-8 対応
フラグ指定不要。\p{} が標準で使用可能
Pattern.UNICODE_CHARACTER_CLASS
(?U)Java 7以降。\w 等を Unicode 対応にする
/pattern/uu 修飾子で UTF-8 モードを有効化
比較メモ: Go と Python 3 はデフォルトで Unicode 対応。JavaScript は u/v フラグの明示的指定が必要
JavaScript は x フラグ非対応
代替: 文字列を連結して構築
re.VERBOSE
(?x)空白を無視し # でコメントが書ける
* 複雑なパターンの可読性向上に有用
RE2 エンジンは x フラグ非対応
Pattern.COMMENTS
(?x)空白を無視し # でコメントが書ける
/pattern/xx 修飾子で空白無視・コメント許可
比較メモ: JavaScript と Go は冗長モード非対応。複雑なパターンの可読性では Python/Java/PCRE が優位
/pattern/gg フラグで全マッチを検索
re.findall()
re.finditer()関数で制御。フラグは不要
FindAllString()Regexp.FindAllString() で全マッチ取得
* フラグではなくメソッドで制御
Matcher.find() を繰り返しwhile(m.find()) で全マッチ取得
* フラグではなくAPI制御
/pattern/gg 修飾子で全マッチ
* 一部の実装では preg_match_all() で制御
比較メモ: JS/PCRE はフラグで制御するが、Python/Go/Java は API(メソッド/関数)で全マッチを取得する設計
JavaScript はインラインフラグ非対応
RegExp コンストラクタの第2引数でフラグ指定
(?i) (?m) (?s) (?x)パターン先頭でフラグ指定可能
* (?i:abc) で部分適用も可(Python 3.6以降)
(?i) (?m) (?s)パターン先頭でフラグ指定可能
* (?i:abc) で部分適用も可
(?i) (?m) (?s) (?x)パターン先頭でフラグ指定可能
* (?i:abc) で部分適用も可
(?i) (?m) (?s) (?x)パターン先頭でフラグ指定可能
* (?i:abc) で部分適用も可
比較メモ: JavaScript のみインラインフラグ非対応。他の言語は (?flags:pattern) で部分的にフラグを適用できる
$1 $2$n でn番目のキャプチャを参照
* str.replace(/pattern/, "$1")
\1 \2\n でn番目のキャプチャを参照
* re.sub(pattern, r"\1", text)
${1} $1$n でn番目のキャプチャを参照
* Regexp.ReplaceAllString()
$1 $2$n でn番目のキャプチャを参照
* Matcher.replaceAll("$1")
$1 \1$n または \n でキャプチャを参照
* preg_replace で使用
比較メモ: Python は \1 形式、JS/Java/Go は $1 形式。混同しやすいので注意
$<name>$<name> で名前付きグループを参照
* ES2018以降
\g<name>\g<name> で名前付きグループを参照
${name}${name} で名前付きグループを参照
${name}${name} で名前付きグループを参照
* Java 7以降
${name}${name} で名前付きグループを参照
比較メモ: Python のみ \g<name> 形式。他の言語は ${name} または $<name> 形式
$&$& でマッチ全体を参照
* $` はマッチ前、$' はマッチ後
\g<0>\g<0> でマッチ全体を参照
$0$0 でマッチ全体を参照
$0$0 でマッチ全体を参照
$0 \0$0 または \0 でマッチ全体を参照
比較メモ: JS は $&、Python は \g<0>、Go/Java/PCRE は $0 とそれぞれ異なる
JavaScript は条件分岐パターン非対応
(?(id)yes|no)グループidがマッチしたらyesパターン、しなければnoパターン
RE2 エンジンは条件分岐非対応
Java は条件分岐パターン非対応
(?(id)yes|no)グループidに基づく条件分岐
* 先読みの結果に基づく条件分岐も可能
比較メモ: 条件分岐パターンは Python と PCRE のみ対応。JS/Go/Java は非対応
JavaScript は再帰パターン非対応
re モジュールは非対応
regex モジュールで (?R) が使用可能
RE2 エンジンは再帰パターン非対応
Java は再帰パターン非対応
(?R)
(?P>name)(?R) でパターン全体を再帰。(?P>name) で名前付きグループを再帰
* 入れ子の括弧や HTML タグのマッチに有用
比較メモ: 再帰パターンは PCRE のみネイティブ対応。括弧の対応チェック等の入れ子構造のマッチに使う
JavaScript はサブルーチン非対応
re モジュールは非対応
regex モジュールで対応
RE2 エンジンはサブルーチン非対応
Java はサブルーチン非対応
(?1)
(?&name)
(?P>name)(?1) で1番目のグループを再利用
* 同じパターンの繰り返し定義を避けられる
比較メモ: サブルーチン呼び出しは PCRE のみ対応。正規表現内でグループパターンを関数のように再利用できる
JavaScript は正規表現内コメント非対応
// コメントで別行に記述
(?#comment)インラインコメント。(?x) モードでは # がコメント
RE2 エンジンはコメント構文非対応
(?#comment)インラインコメント。(?x) モードでは # がコメント
(?#comment)インラインコメント。x修飾子で # がコメント
比較メモ: JS/Go はコメント構文非対応。Python/Java/PCRE は (?#...) でインラインコメントが書ける
JavaScript は非対応
re モジュールは非対応
regex モジュールで対応
RE2 エンジンは非対応
Java は非対応
(?|pattern1|pattern2)各選択肢のキャプチャ番号をリセット(共有)
* 選択肢ごとに $1 の内容が変わる
比較メモ: ブランチリセットは PCRE のみ対応。選択肢パターンでキャプチャ番号を共有できる
JavaScript は非対応
re モジュールは非対応
regex モジュールで一部対応
RE2 エンジンは非対応
Java は非対応
(*SKIP) (*FAIL)
(*PRUNE) (*THEN)バックトラックの挙動を細かく制御
* (*SKIP)(*FAIL) で「ここまでスキップして失敗」
比較メモ: バックトラック制御動詞は PCRE のみの高度な機能。複雑なパターンの最適化に使われる
\n \r \r\n\n (LF) / \r (CR) を個別に指定
\n \r \r\n\n (LF) / \r (CR) を個別に指定
\n \r\n (LF) / \r (CR) を個別に指定
\n \r \R\R は任意の改行シーケンスにマッチ
* Java 8以降。\R は \r\n, \r, \n 等すべてにマッチ
\n \r \R\R は任意の改行シーケンスにマッチ
* CR, LF, CRLF, VT, FF, NEL すべて
比較メモ: \R(任意の改行)は Java と PCRE のみ対応。クロスプラットフォームのテキスト処理で有用
バックトラック型NFAV8/SpiderMonkey等。Perlベースの正規表現エンジン
バックトラック型NFA独自実装のNFAエンジン
* re2 パッケージでRE2エンジンも利用可能
RE2(DFA/NFA ハイブリッド)線形時間保証。バックトラックなし
* 後方参照・先読み・後読みが使えない代わりに安全
バックトラック型NFAjava.util.regex。Perlベース
バックトラック型NFAPerl Compatible Regular Expressions
* 最も高機能だがReDoSリスクがある
比較メモ: Go の RE2 はバックトラックを使わないため ReDoS(正規表現サービス拒否攻撃)に強い。他のエンジンは高機能だが悪意あるパターンに注意が必要
よくある質問
正規表現の基本的な構文は言語間で共通ですか?
基本的な構文の多くは言語間で共通です。文字クラス [abc]、量指定子(*、+、?、{n,m})、アンカー(^、$)、キャプチャグループ (...)、非キャプチャグループ (?:...)、OR演算子 | などは、JavaScript・Python・Go・Java・PCRE のすべてで同じ構文が使えます。ただし、名前付きキャプチャ((?<name>) vs (?P<name>))、後方参照の置換構文($1 vs \1)、Unicode サポートの範囲、フラグの指定方法、先読み・後読みの対応状況は言語間で異なります。特に Go の RE2 エンジンは後方参照・先読み・後読みに非対応、Java は \p{} の書き方が独自(\p{IsL})など、細部で差異があるため、本ツールでの確認を推奨します。
後読み(lookbehind)に対応していない言語はありますか?
Go の RE2 エンジンは先読み・後読みの両方に対応していません。RE2 は正規表現マッチングを線形時間で保証する設計思想のため、計算コストが高い先読み・後読み機能を意図的に除外しています。JavaScript は ES2018 以前は後読み非対応でしたが、ES2018 で (?<=...) と (?<!...) が追加され、現在の主要ブラウザ(Chrome 62+, Firefox 78+, Safari 16.4+)では使用可能です。Python は固定長パターンのみ後読みに対応しており、可変長パターンでは使用できません(例: (?<=abc) は可能だが (?<=a+) はエラー)。PCRE は最も柔軟で、可変長の後読みパターンも一部サポートしています。Java は基本的に固定長後読みを推奨しますが、一部の可変長パターンも動作します。
名前付きキャプチャの書き方は言語によって違いますか?
はい、名前付きキャプチャの構文は言語間で大きく異なります。JavaScript と Java は (?<name>pattern) 形式を使用し、ES2018/Java 7 以降で対応しています。Python と Go は (?P<name>pattern) 形式を使用します(Python の P は「Python Extension」の略とも言われます)。PCRE は最も柔軟で、(?P<name>pattern)、(?<name>pattern)、(?'name'pattern) の3つの構文すべてに対応しています。後方参照での参照方法も異なり、JavaScript は \k<name>、Python は (?P=name)、Java は \k<name>、PCRE は (?P=name) と \k<name> の両方に対応します。置換文字列での参照も、JavaScript は $<name>、Python は \g<name>、Java/Go/PCRE は ${name} とそれぞれ異なるため、言語をまたいだ開発時は特に注意が必要です。
JavaScript の正規表現で最近追加された機能は?
JavaScript の正規表現は近年急速に進化しています。ES2018 では後読み(lookbehind)の (?<=...) / (?<!...)、名前付きキャプチャ (?<name>...)、s フラグ(dotAll)、Unicode プロパティエスケープ \p{...} が追加されました。ES2020 では String.prototype.matchAll() が追加され、g フラグでの全マッチ結果をイテレータで取得できるようになりました。ES2022 では d フラグ(hasIndices)が追加され、マッチのインデックス情報を取得可能に。ES2024 では v フラグ(unicodeSets)が追加され、\p{} の集合演算(差集合 [A--B]、積集合 [A&&B])や文字列プロパティ \p{RGI_Emoji} が使えるようになりました。v フラグは u フラグの上位互換であり、今後の Unicode 対応正規表現では v フラグの使用が推奨されます。
Go の正規表現エンジン(RE2)の特徴と制限は?
Go の正規表現エンジン RE2 は、Google の Russ Cox が開発した安全性を重視したエンジンです。最大の特徴は「入力サイズに対して線形時間で動作することが保証されている」点です。従来のバックトラック型NFA(Perl/Java/Python等)は、悪意あるパターンや特定の入力で指数関数的に処理時間が増大する ReDoS(正規表現サービス拒否攻撃)の脆弱性がありますが、RE2 はこれを原理的に防ぎます。代わりに、以下の高度な機能が使えません: (1) 後方参照 \1(キャプチャしたグループの再利用)、(2) 先読み (?=...) / (?!...)、(3) 後読み (?<=...) / (?<!...)、(4) 独占的量指定子 a++、(5) 原子グループ (?>...)、(6) 条件分岐 (?(id)yes|no)。ただし、POSIX 文字クラス [[:alpha:]] や Unicode プロパティ \p{L} には対応しており、多くの実用的なパターンは記述可能です。
PCRE と他の正規表現エンジンの違いは?
PCRE(Perl Compatible Regular Expressions)は PHP の preg_match() 等で使われるエンジンで、全エンジンの中で最も機能が豊富です。PCRE でのみ使える主な機能: (1) 再帰パターン (?R) — 入れ子の括弧やHTMLタグのマッチに有用。(2) サブルーチン呼び出し (?1) / (?&name) — 定義済みグループパターンの再利用。(3) ブランチリセット (?|...) — 選択肢間でキャプチャ番号を共有。(4) バックトラック制御動詞 (*SKIP)(*FAIL) 等 — マッチの挙動を細かく制御。(5) 書記素クラスタ \X — 絵文字等の複合文字にマッチ。(6) \R(任意の改行)は PCRE と Java のみ対応。一方で、PCRE はバックトラック型NFAのため、ReDoS リスクがあり、ユーザー入力をパターンに使う場合は注意が必要です。バージョンも PCRE1(レガシー)と PCRE2(PHP 7.3以降)で機能差があるため、使用環境の確認が重要です。
Unicode 文字にマッチさせるにはどうすればいい?
Unicode 文字のマッチ方法は言語ごとに異なります。JavaScript: \p{L}(全Unicode文字)や \p{Script=Hiragana}(ひらがな)が使用可能ですが、u または v フラグの指定が必須です。例: /\p{Script=Hiragana}+/u でひらがなにマッチ。Python: 標準の re モジュールは \p{} 構文に非対応です。[\u3040-\u309F] のような範囲指定か、regex モジュール(pip install regex)のインストールが必要です。Go: デフォルトで UTF-8 対応しており、\p{L}、\p{Hiragana}、\p{Han} がフラグなしで使用可能です。Java: \p{IsHiragana} のように Is プレフィックスを付ける形式です(\p{L} はプレフィックスなし)。PCRE: \p{L}、\p{Hiragana} が使えますが、u 修飾子で UTF-8 モードを有効にする必要があります。日本語テキストを扱う場合は、ひらがな \p{Hiragana}、カタカナ \p{Katakana}、漢字 \p{Han} の3つのスクリプトを組み合わせて使用します。
正規表現のパフォーマンスを改善するコツは?
正規表現のパフォーマンス改善には以下のテクニックが有効です。(1) 具体的なパターンを使う: .* のような曖昧なパターンより [a-z]+ のように具体的に指定する。バックトラックの回数が減り高速化します。(2) 非貪欲を適切に使う: .*? は .* より高速な場合が多いですが、常にではありません。期待するマッチに応じて使い分けてください。(3) アンカーを活用: ^ や $ でマッチ開始位置を限定すると、エンジンが無駄な位置でのマッチ試行を省略できます。(4) 独占的量指定子を使う(Java/PCRE): a++ はバックトラックを禁止するため、マッチ失敗時の処理が高速です。(5) キャプチャ不要なグループは (?:...) を使う: キャプチャグループはメモリを消費するため、参照しないグループは非キャプチャにします。(6) ReDoS を避ける: (a+)+ や (a|a)* のようなネストした量指定子は指数関数的な処理時間になる可能性があります。特にユーザー入力をパターンに使う場合は RE2(Go)のような安全なエンジンを検討してください。
逆引き・早見表ツール一覧
すべて見るこのツールについて
使い方
- 検索欄に構文(例: (?<=) )やキーワード(例: 後読み、名前付き)を入力する
- 「JavaScript」「Python」「Go」「Java」「PCRE」のフィルターで見たい言語に絞り込む
- カテゴリフィルターで「先読み・後読み」「フラグ」など目的のカテゴリを選択する
- 各カードで5言語の構文を並べて比較。非対応の場合はグレーアウト表示される
- 「比較メモ」で言語間の重要な違いや注意点を確認する
このツールの特徴
- ✓5つの言語/エンジンを横断比較:JavaScript・Python・Go・Java・PCRE の同じ操作に対応する正規表現構文を並べて表示。言語移行時の「この構文どう書く?」をすぐ解決
- ✓非対応構文の明示:Go の RE2 エンジンで使えない先読み・後読みや、JavaScript にない冗長モードなど、非対応の構文をグレーアウトで明示。「なぜ動かないのか」がすぐ分かる
- ✓「やりたいこと」から逆引き:「名前付きキャプチャ」「後読み」「Unicode文字にマッチ」など、目的から構文を検索できる
- ✓比較メモで違いを解説:名前付きキャプチャの構文差((?<name>) vs (?P<name>))やフラグの指定方法の違いなど、重要なポイントを補足説明
- ✓置換構文もカバー:$1 vs \\1、$<name> vs \\g<name> など、置換時のキャプチャ参照構文の違いも網羅
- ✓PCRE の高度な機能:再帰パターン、サブルーチン呼び出し、バックトラック制御動詞など、PCRE 固有の高度な構文も掲載
こんなときに便利
- •Python で書いた正規表現を JavaScript に移植するとき、構文の違いを確認したい
- •Go で正規表現を書いたら動かない。RE2 エンジンの制限を確認したい
- •名前付きキャプチャを使いたいが、各言語での書き方の違いを調べたい
- •Unicode 文字(日本語等)にマッチする正規表現を各言語で書きたい
- •PHP の PCRE でしか使えない機能を確認したい(再帰パターン・制御動詞等)
- •正規表現の置換構文($1 vs \\1)が言語によって違うので確認したい
- •ReDoS 対策として Go の RE2 エンジンへの移行を検討しているが、使えなくなる機能を把握したい
なぜ「正規表現構文 横断検索」が必要なのか
正規表現は「一度覚えればどの言語でも使える」と思われがちですが、実際には言語間で多くの構文差があります。基本的なパターン(文字クラス・量指定子・アンカー等)は共通していますが、名前付きキャプチャ、後読み、Unicode サポート、フラグ指定、置換構文など、実用上重要な機能ほど言語間の差異が大きくなります。
例えば、Python で (?P<year>\\d4) と書いていた名前付きキャプチャを JavaScript に移植する際は (?<year>\\d4) に変更が必要です。Go では後方参照 \\1 が使えないため、パターン設計自体を見直す必要があります。PHP(PCRE)で再帰パターン (?R) を使った入れ子構造のマッチを他の言語に移植するのは、根本的なアプローチの変更が求められます。
既存のリファレンスは「Python の正規表現一覧」「JavaScript の RegExp」のように単一言語に特化しており、5つの言語を横断的に比較し、「やりたいこと」を起点に逆引きできるツールは日本語ではほとんど存在しません。言語間の非互換性を把握していないと、移植時に「なぜ動かないのか」の調査に多くの時間を費やすことになります。
このツールは正規表現の「やりたいこと」を起点に、5つの言語/エンジンの構文を一覧比較することで、言語間の移植コストを最小化し、開発者の生産性を向上させることを目指しています。実際に正規表現をテストしたい場合は 正規表現テスター もご活用ください。
各言語の正規表現エンジンの特徴
- •JavaScript:V8(Chrome/Node.js)やSpiderMonkey(Firefox)に組み込まれたバックトラック型NFAエンジンを使用。ES2018 で後読み・名前付きキャプチャ・dotAll(sフラグ)・Unicode プロパティエスケープが追加され、ES2024 では v フラグ(Unicode Sets)でさらに強化されました。ブラウザ内で動作するため、クライアントサイドのバリデーションやテキスト処理で広く使用されています。注意点として、RegExp オブジェクトの lastIndex が状態を持つため、g フラグ使用時は exec() の連続呼び出しに注意が必要です。
- •Python:標準ライブラリの re モジュールは独自実装のバックトラック型NFAエンジンです。Python 3 ではデフォルトで Unicode 対応しており、\w や \d が Unicode 文字にマッチします(re.ASCII で制限可能)。名前付きキャプチャは (?P<name>) という独自構文で、Perl/PCRE の影響を受けつつも独自の拡張があります。冗長モード(re.VERBOSE / (?x))による可読性の高い正規表現の記述が特徴です。なお、標準 re モジュールは \p{}} 構文に非対応で、Unicode プロパティを使うには regex モジュール(pip install regex)が必要です。
- •Go:Google の RE2 エンジンを使用。最大の特徴は「入力サイズに対して線形時間で動作する」ことが保証されている点です。バックトラックを使用しないDFA/NFAハイブリッド設計のため、ReDoS(正規表現サービス拒否攻撃)に対して原理的に安全です。代わりに、後方参照・先読み・後読み・独占的量指定子・原子グループ・条件分岐・再帰パターンなどの高度な機能は使えません。ただし、POSIX 文字クラス [[:alpha:]] や Unicode プロパティ \p{ L } にはデフォルトで対応しており、実用的なパターンの大部分は記述可能です。セキュリティが重要なサーバーサイドアプリケーションでの使用に適しています。
- •Java:java.util.regex パッケージのバックトラック型NFAエンジンです。Perl の正規表現をベースにしており、後方参照・先読み・後読み・独占的量指定子・原子グループなど豊富な機能を持ちます。Java 7 で名前付きキャプチャ (?<name>)、Java 8 で \R(任意の改行)、Java 9 で \b{ g }(書記素境界)が追加されました。注意点として、Java の文字列リテラル内ではバックスラッシュを二重にする必要があるため(例: "\\d+" で \d+)、raw 文字列のない Java では正規表現の記述がやや冗長になります。Pattern.UNICODE_CHARACTER_CLASS フラグで \w 等を Unicode 対応にできます。
- •PCRE:Perl Compatible Regular Expressions の略で、PHP の preg_match() / preg_replace() や Nginx の location ディレクティブなどで使われるエンジンです。全エンジンの中で最も機能が豊富で、再帰パターン (?R)、サブルーチン呼び出し (?1)、ブランチリセット (?|...)、バックトラック制御動詞 (*SKIP)(*FAIL)、書記素クラスタ \X などの独自機能を持ちます。現在は PCRE2(2015年リリース、PHP 7.3以降で採用)が主流で、Unicode サポートが大幅に強化されています。JIT コンパイルによる高速化も特徴です。ただしバックトラック型NFAのため、ReDoS リスクがあり、ユーザー入力をパターンに含める場合は pcre2_set_match_limit() 等での対策が推奨されます。
正規表現の歴史と各エンジンの系譜
正規表現(Regular Expression)の歴史は1950年代の数学者 Stephen Kleene による正規言語の理論に遡ります。1968年に Ken Thompson が UNIX のテキストエディタ ed に正規表現を実装し、以降 grep(1973年)、sed、awk と UNIX ツール群に広がりました。1986年に Henry Spencer が正規表現ライブラリを公開し、これが多くの実装の基盤となりました。
1987年の Perl 1.0 で正規表現は大きく進化し、\\d、\\w、\\s 等のショートハンド、非貪欲量指定子、先読みなどが追加されました。現在の主要な正規表現エンジンのほとんどは Perl の影響を受けており、「Perl 互換」を名乗る PCRE(1997年、Philip Hazel が開発)は PHP や Apache、Nginx 等で広く採用されています。
2006年に Google の Russ Cox が RE2 を開発し、正規表現の安全性に新しいアプローチをもたらしました。RE2 は Thompson NFA に基づく実装で、バックトラックを使わないことで線形時間を保証します。Go 言語はこの RE2 を標準の正規表現エンジンとして採用しています。近年は JavaScript も ES2018 以降で急速に機能を拡充しており、v フラグ(ES2024)による Unicode Sets サポートなど、モダンな正規表現機能の強化が進んでいます。