Namespaces
Variants

Modified ECMAScript regular expression grammar

From cppreference.net

このページでは、 std::basic_regex syntax_option_type ECMAScript に設定して構築される場合に使用される正規表現文法について説明します。他のサポートされている正規表現文法については、 syntax_option_type を参照してください。

C++における ECMAScript 3 正規表現文法は、 ECMA-262 文法 を基にしており、以下に (C++のみ) と記された修正が加えられています。

目次

概要

修正された正規表現文法 は、主にECMAScript RegExp文法であり、 ClassAtom の下でのロケールに関するPOSIXタイプの拡張が加えられています。等価性チェックと数値解析に関するいくつかの明確化が行われています。ここにある多くの例については、ブラウザのコンソールで同等のものを試すことができます:

function match(s, re) { return s.match(new RegExp(re)); }

標準における「引用規格」はECMAScript 3を規定しています。ここではECMAScript 5.1仕様へリンクしています。これはECMAScript 3からわずかな変更のみのバージョンであり、HTML版も存在するためです。この方言の機能概要については、 MDN Guide on JavaScript RegExp を参照してください。

代替案

正規表現パターンは、1つ以上の Alternative が分離演算子 | で区切られたシーケンスです(言い換えれば、分離演算子は最も優先順位が低くなります)。

Pattern ::

論理和

論理和 ::

代替案
代替案 | 論理和

このパターンは最初に Disjunction をスキップし、 左側の Alternative と正規表現の残りの部分(Disjunctionの後)のマッチングを試みます。

失敗した場合、左側の Alternative をスキップして右側の Disjunction (正規表現の残りの部分が続く)とのマッチを試みます。

左の Alternative と右の Disjunction 、および正規表現の残りの部分すべてに選択ポイントがある場合、左の Alternative の次の選択肢に移る前に、式の残りの部分のすべての選択肢が試行されます。左の Alternative の選択肢が尽きた場合、左の Alternative の代わりに右の Disjunction が試行されます。

スキップされた Alternative 内の任意の捕捉括弧は空の部分一致を生成します。

#include <cstddef>
#include <iostream>
#include <regex>
#include <string>
void show_matches(const std::string& in, const std::string& re)
{
    std::smatch m;
    std::regex_search(in, m, std::regex(re));
    if (!m.empty())
    {
        std::cout << "input=[" << in << "], regex=[" << re << "]\n  "
                     "prefix=[" << m.prefix() << "]\n  smatch: ";
        for (std::size_t n = 0; n < m.size(); ++n)
            std::cout << "m[" << n << "]=[" << m[n] << "] ";
        std::cout << "\n  suffix=[" << m.suffix() << "]\n";
    }
    else
        std::cout << "input=[" << in << "], regex=[" << re << "]: NO MATCH\n";
}
int main()
{
    show_matches("abcdef", "abc|def");
    show_matches("abc", "ab|abc"); // 左の選択肢が最初にマッチ
    // 入力に対する左の選択肢(a)のマッチに続いて
    // 残りの正規表現(c|bc)が成功し、その結果
    // m[1]="a" と m[4]="bc" となる
    // スキップされた選択肢(ab)と(c)はそれらの部分マッチ
    // m[3]とm[5]を空にする
    show_matches("abc", "((a)|(ab))((c)|(bc))");
}

出力:

input=[abcdef], regex=[abc|def]
  prefix=[]
  smatch: m[0]=[abc]
  suffix=[def]
input=[abc], regex=[ab|abc]
  prefix=[]
  smatch: m[0]=[ab]
  suffix=[c]
input=[abc], regex=[((a)|(ab))((c)|(bc))]
  prefix=[]
  smatch: m[0]=[abc] m[1]=[a] m[2]=[a] m[3]=[] m[4]=[bc] m[5]=[] m[6]=[bc]
  suffix=[]

用語

Alternative は空であるか、または Term のシーケンス( Term 間に区切り文字なし)です

代替 ::

[空]
代替 用語

空の 代替 は常に一致し、いかなる入力も消費しません。

連続した Term は、入力の連続する部分を同時にマッチングしようと試みます。

左の Alternative 、右の Term 、および正規表現の残りの部分すべてに選択ポイントがある場合、右の Term の次の選択肢に進む前に、式の残りの部分のすべての選択肢が試行され、左の Alternative の次の選択肢に進む前に、右の Term のすべての選択肢が試行されます。

#include <cstddef>
#include <iostream>
#include <regex>
#include <string>
void show_matches(const std::string& in, const std::string& re)
{
    std::smatch m;
    std::regex_search(in, m, std::regex(re));
    if (!m.empty())
    {
        std::cout << "input=[" << in << "], regex=[" << re << "]\n  "
                     "prefix=[" << m.prefix() << "]\n  smatch: ";
        for (std::size_t n = 0; n < m.size(); ++n)
            std::cout << "m[" << n << "]=[" << m[n] << "] ";
        std::cout << "\n  suffix=[" << m.suffix() << "]\n";
    }
    else
        std::cout << "input=[" << in << "], regex=[" << re << "]: NO MATCH\n";
}
int main()
{
    show_matches("abcdef", ""); // 空の正規表現は単一の空のAlternative
    show_matches("abc", "abc|"); // 左のAlternativeが最初にマッチ
    show_matches("abc", "|abc"); // 左のAlternativeが最初にマッチし、abcは未マッチのまま
}

出力:

input=[abcdef], regex=[]
  prefix=[]
  smatch: m[0]=[]
  suffix=[abcdef]
input=[abc], regex=[abc|]
  prefix=[]
  smatch: m[0]=[abc]
  suffix=[]
input=[abc], regex=[|abc]
  prefix=[]
  smatch: m[0]=[]
  suffix=[abc]

量指定子

  • Term は、以下の Assertion か、以下の Atom か、または Atom の直後に Quantifier が続くものです

用語 ::

アサーション
アトム
アトム 量指定子

Quantifier は、 greedy 量指定子(単一の QuantifierPrefix のみで構成される)または non-greedy 量指定子(1つの QuantifierPrefix に疑問符 ? が続く)のいずれかです。

量化子 ::

量化子接頭辞
量化子接頭辞 ?

QuantifierPrefix は以下のように、繰り返しの最小回数と最大回数の2つの数値を決定します:

量指定子接頭辞 最小値 最大値
* ゼロ 無限大
+ 1 無限大
? ゼロ 1
{ DecimalDigits } DecimalDigitsの値 DecimalDigitsの値
{ DecimalDigits , } DecimalDigitsの値 無限大
{ DecimalDigits , DecimalDigits } カンマ前のDecimalDigitsの値 カンマ後のDecimalDigitsの値

個々の DecimalDigits の値は、各数字に対して std::regex_traits::value (C++ only) を呼び出すことによって取得されます。

Atom の後に Quantifier が続く場合、 Atom Quantifier で指定された回数だけ繰り返されます。 Quantifier non-greedy (非貪欲)に設定することができ、その場合 Atom パターンは正規表現の残りの部分に一致する最小限の回数だけ繰り返されます。また、 greedy (貪欲)に設定することもでき、その場合 Atom パターンは正規表現の残りの部分に一致する最大限の回数だけ繰り返されます。

Atom パターンが繰り返されるのであって、それがマッチする入力が繰り返されるわけではありません。したがって、 Atom の異なる繰り返しは、異なる入力部分文字列にマッチすることができます。

Atom と正規表現の残りの部分の両方に選択肢がある場合、 Atom はまず可能な限り多く(または non-greedy の場合は少なく)マッチします。正規表現の残りの部分のすべての選択肢は、 Atom の最後の繰り返しの次の選択肢に進む前に試行されます。 Atom の最後(n回目)の繰り返しのすべての選択肢は、 Atom の最後から2番目(n–1回目)の繰り返しの次の選択肢に進む前に試行されます。この時点で、 Atom の繰り返し回数が増減している可能性があります。これらは(再び、可能な限り少ないか多いかから開始して)すべて試行された後、 Atom の(n-1)回目の繰り返しの次の選択肢に進み、以降同様に続きます。

この Atom' のキャプチャは、繰り返されるたびにクリアされます(以下の "(z)((a+)?(b+)?(c))*" の例を参照)

#include <cstddef>
#include <iostream>
#include <regex>
#include <string>
void show_matches(const std::string& in, const std::string& re)
{
    std::smatch m;
    std::regex_search(in, m, std::regex(re));
    if (!m.empty())
    {
        std::cout << "input=[" << in << "], regex=[" << re << "]\n  "
                     "prefix=[" << m.prefix() << "]\n  smatch: ";
        for (std::size_t n = 0; n < m.size(); ++n)
            std::cout << "m[" << n << "]=[" << m[n] << "] ";
        std::cout << "\n  suffix=[" << m.suffix() << "]\n";
    }
    else
        std::cout << "input=[" << in << "], regex=[" << re << "]: NO MATCH\n";
}
int main()
{
    // 貪欲マッチ、[a-z]を4回繰り返す
    show_matches("abcdefghi", "a[a-z]{2,4}");
    // 非貪欲マッチ、[a-z]を2回繰り返す
    show_matches("abcdefghi", "a[a-z]{2,4}?");
    // 量指定子の選択ポイント順序により、2回の繰り返しでマッチ
    // 最初は部分文字列"aa"にマッチし、
    // 2回目は部分文字列"ba"にマッチし、"ac"はマッチしない
    // ("ba"はキャプチャ句m[1]に現れる)
    show_matches("aabaac", "(aa|aabaac|ba|b|c)*");
    // 量指定子の選択ポイント順序により、この正規表現は
    // 10と15の最大公約数を計算する
    // (答えは5で、m[1]に"aaaaa"が設定される)
    show_matches("aaaaaaaaaa,aaaaaaaaaaaaaaa", "^(a+)\\1*,\\1+$");
    // 部分文字列"bbb"はキャプチャ句m[4]に現れない
    // なぜなら、アトム(a+)?(b+)?(c)の2回目の繰り返しが
    // 部分文字列"ac"にマッチするときにクリアされるため
    // 注意: gccはこれを誤って処理する - ECMA-262 21.2.2.5.1で要求される
    // matches[4]キャプチャグループを正しくクリアせず、
    // そのグループに対して誤って"bbb"をキャプチャする
    show_matches("zaacbbbcac", "(z)((a+)?(b+)?(c))*");
}

出力:

input=[abcdefghi], regex=[a[a-z]{2,4}]
  prefix=[]
  smatch: m[0]=[abcde]
  suffix=[fghi]
input=[abcdefghi], regex=[a[a-z]{2,4}?]
  prefix=[]
  smatch: m[0]=[abc]
  suffix=[defghi]
input=[aabaac], regex=[(aa|aabaac|ba|b|c)*]
  prefix=[]
  smatch: m[0]=[aaba] m[1]=[ba]
  suffix=[ac]
input=[aaaaaaaaaa,aaaaaaaaaaaaaaa], regex=[^(a+)\1*,\1+$]
  prefix=[]
  smatch: m[0]=[aaaaaaaaaa,aaaaaaaaaaaaaaa] m[1]=[aaaaa]
  suffix=[]
input=[zaacbbbcac], regex=[(z)((a+)?(b+)?(c))*]
  prefix=[]
  smatch: m[0]=[zaacbbbcac] m[1]=[z] m[2]=[ac] m[3]=[a] m[4]=[] m[5]=[c] 
  suffix=[]

アサーション

アサーション は、入力文字列の部分文字列ではなく条件に一致します。これらは入力から一切文字を消費しません。各 アサーション は以下のいずれかです

アサーション ::

^
$
\ b
\ B
( ? = 論理和 )
( ? ! 論理和 )

アサーション ^ (行頭) が一致します

1) LineTerminator 文字の直後の位置 (これはサポートされない可能性があります) (C++17まで) (これは std::regex_constants::multiline (C++のみ) が有効な場合にのみ保証されます) (C++17以降)
2) 入力の先頭( std::regex_constants::match_not_bol (C++ only) が有効でない限り)

アサーション $ (行末)にマッチします

1) LineTerminator 文字の位置 (これはサポートされない可能性があります) (C++17まで) (これは std::regex_constants::multiline (C++のみ) が有効な場合にのみ保証されます) (C++17以降)
2) 入力の終端( std::regex_constants::match_not_eol (C++ only) が有効でない限り)

上記の2つの表明と以下のAtom . において、 LineTerminator は以下の4つの文字のいずれかです: U+000A ( \n またはラインフィード)、 U+000D ( \r またはキャリッジリターン)、 U+2028 (ラインセパレータ)、または U+2029 (パラグラフセパレータ)

アサーション \b (単語境界) が一致します

1) 単語の先頭(現在の文字が英字、数字、またはアンダースコアであり、前の文字がそれらではない場合)
2) 単語の終端(現在の文字が英字、数字、またはアンダースコアではなく、直前の文字がそれらのいずれかである場合)
3) 入力の先頭が文字、数字、またはアンダースコアである場合(ただし std::regex_constants::match_not_bow (C++ only) が有効な場合を除く)
4) 入力の終端(最後の文字が英字、数字、またはアンダースコアである場合) std::regex_constants::match_not_eow (C++ only) が有効な場合を除く)

アサーション \B (negative word boundary) は以下を除くすべてにマッチします

1) 単語の開始(現在の文字が英字、数字、またはアンダースコアであり、前の文字がそれらのいずれでもないか存在しない場合)
2) 単語の終端(現在の文字が英字、数字、アンダースコアではない場合(またはマッチャーが入力の終端にある場合)、かつ前の文字がそれらのいずれかである場合)

アサーション ( ? = Disjunction ) (ゼロ幅肯定先読み) は、 Disjunction が現在位置で入力にマッチする場合にマッチします

アサーション ( ? ! Disjunction ) (ゼロ幅否定先読み) は、 Disjunction が現在位置で入力に一致しない場合にマッチします。

両方の先読みアサーションにおいて、 Disjunction のマッチング時には、正規表現の残りの部分をマッチさせる前に位置は進みません。また、 Disjunction が現在位置で複数の方法でマッチ可能な場合、最初の方法のみが試行されます。

ECMAScriptは先読み選言へのバックトラッキングを禁止しており、これは正の先読み内からの後方参照が正規表現の残りの部分でどのように動作するかに影響を与えます(以下の例を参照)。負の先読み内からの後方参照は、正規表現の残りの部分から常に未定義となります(なぜなら先読み選言は処理を進めるために失敗しなければならないため)。

注: 先読みアサーションを使用して複数の正規表現間の論理積を作成できます(下記の例を参照)。

#include <cstddef>
#include <iostream>
#include <regex>
#include <string>
void show_matches(const std::string& in, const std::string& re)
{
    std::smatch m;
    std::regex_search(in, m, std::regex(re));
    if (!m.empty())
    {
        std::cout << "input=[" << in << "], regex=[" << re << "]\n  "
                     "prefix=[" << m.prefix() << "]\n  smatch: ";
        for (std::size_t n = 0; n < m.size(); ++n)
            std::cout << "m[" << n << "]=[" << m[n] << "] ";
        std::cout << "\n  suffix=[" << m.suffix() << "]\n";
    {
    else
        std::cout << "input=[" << in << "], regex=[" << re << "]: NO MATCH\n";
}
int main()
{
    // 入力の末尾にあるaにマッチ
    show_matches("aaa", "a$");
    // 最初の単語の末尾にあるoにマッチ
    show_matches("moo goo gai pan", "o\\b");
    // 先読みは最初のbの直後の空文字列にマッチ
    // これによりm[0]は空だがm[1]に"aaa"が格納される
    show_matches("baaabac", "(?=(a+))");
    // 先読みへのバックトラックが禁止されているため、
    // これはaaabaではなくabaにマッチする
    show_matches("baaabac", "(?=(a+))a*b\\1");
    // 先読みによる論理AND: このパスワードは以下の条件を満たす場合にマッチ
    // 少なくとも1つの小文字を含む
    // 少なくとも1つの大文字を含む
    // 少なくとも1つの句読点文字を含む
    // 少なくとも6文字以上である
    show_matches("abcdef", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}");
    show_matches("aB,def", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}");
}

出力:

input=[aaa], regex=[a$]
  prefix=[aa]
  smatch: m[0]=[a] 
  suffix=[]
input=[moo goo gai pan], regex=[o\b]
  prefix=[mo]
  smatch: m[0]=[o] 
  suffix=[ goo gai pan]
input=[baaabac], regex=[(?=(a+))]
  prefix=[b]
  smatch: m[0]=[] m[1]=[aaa] 
  suffix=[aaabac]
input=[baaabac], regex=[(?=(a+))a*b\1]
  prefix=[baa]
  smatch: m[0]=[aba] m[1]=[a] 
  suffix=[c]
input=[abcdef], regex=[(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}]: NO MATCH
input=[aB,def], regex=[(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}]
  prefix=[]
  smatch: m[0]=[aB,def] 
  suffix=[]

アトム

Atom は以下のいずれかになります:

Atom ::

PatternCharacter
.
\ AtomEscape
CharacterClass
( Disjunction )
( ? : Disjunction )

where AtomEscape ::

DecimalEscape
CharacterEscape
CharacterClassEscape

異なる種類の原子は異なる方法で評価されます。

サブ式

Atom ( Disjunction ) はマークされた部分式です:これは Disjunction を実行し、 Disjunction によって消費された入力部分文字列のコピーを、この時点で正規表現全体においてマークされた部分式の左開き括弧 ( が遭遇された回数に対応するインデックスのサブマッチ配列に格納します。

std::match_results で返されることに加えて、キャプチャされた部分マッチはバックリファレンス( \1 \2 ...)としてアクセス可能であり、正規表現内で参照できます。 std::regex_replace はバックリファレンスに \ の代わりに $ を使用し( $1 $2 ...)、これは String.prototype.replace (ECMA-262、パート15.5.4.11)と同様の方法です。

Atom ( ? : Disjunction ) (非マーキング部分式)は単に Disjunction を評価し、その結果をサブマッチに保存しません。これは純粋に字句的なグループ化です。

後方参照

DecimalEscape ::

DecimalIntegerLiteral [ lookahead DecimalDigit ]

\ が最初の桁が 0 でない10進数 N に続く場合、そのエスケープシーケンスは 後方参照 と見なされます。値 N は各桁に対して std::regex_traits::value (C++ only) を呼び出し、それらの結果を10進算術を用いて結合することで得られます。 N が正規表現全体における左キャプチャ括弧の総数より大きい場合はエラーとなります。

後方参照 \N Atom として現れる場合、それは現在サブマッチ配列のN番目の要素に格納されているものと同じ部分文字列にマッチします。

10進数エスケープ \0 は後方参照では ありません :これは NUL 文字を表す文字エスケープです。この後に10進数字を続けることはできません。

前述の通り、 std::regex_replace は後方参照( $1 $2 、...)に \ ではなく $ を使用することに注意してください。

単一文字マッチ

Atom . は、入力文字列から LineTerminator ( U+000D , U+000A , U+2029 、または U+2028 ) を除く任意の1文字にマッチし、それを消費します。

Atom である PatternCharacter (ここで PatternCharacter SourceCharacter のうち ^ $ \ . * + ? ( ) [ ] { } | を除く任意の文字)は、入力から1文字を読み取り、その文字がこの PatternCharacter と等しい場合に一致します。

この文字および他のすべての単一文字マッチの等価性は以下のように定義されます:

1) std::regex_constants::icase が設定されている場合、 std::regex_traits::translate_nocase の戻り値が等しければ文字は等しいとみなされる (C++ only)
2) それ以外の場合、 std::regex_constants::collate が設定されている場合、 std::regex_traits::translate の戻り値が等しい場合に文字は等しいとみなされる (C++のみ)
3) それ以外の場合、文字は operator == true を返す場合に等しい。

Atom は、エスケープ文字 \ に続く CharacterEscape および特殊な DecimalEscape \0 で構成され、入力から1文字を消費してマッチングします。これは、その文字が CharacterEscape によって表される文字と等しい場合に行われます。以下の文字エスケープシーケンスが認識されます:

CharacterEscape ::

ControlEscape
c ControlLetter
HexEscapeSequence
UnicodeEscapeSequence
IdentityEscape

ここで、 ControlEscape は以下の5つの文字のいずれかです: f n r t v

ControlEscape Code Unit Name
f U+000C フォームフィード
n U+000A 改行
r U+000D キャリッジリターン
t U+0009 水平タブ
v U+000B 垂直タブ

ControlLetter は任意の小文字または大文字のASCII文字であり、この文字エスケープは ControlLetter のコードユニットの値を 32 で割った余りに等しいコードユニットの文字にマッチします。例えば、 \cD \cd はどちらもコードユニット U+0004 (EOT) にマッチします。なぜなら 'D' は U+0044 であり 0x44 % 32 == 4 、また 'd' は U+0064 であり 0x64 % 32 == 4 となるためです。

HexEscapeSequence は、文字 x に正確に2つの HexDigit が続く形式です(ここで HexDigit 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F のいずれかです)。この文字エスケープは、2桁の16進数の数値と等しいコードユニットを持つ文字に一致します。

UnicodeEscapeSequence は、文字 u に正確に4つの HexDigit が続くものです。この文字エスケープは、この4桁の16進数の数値と等しいコードユニットを持つ文字に一致します。値がこの std::basic_regex CharT に収まらない場合、 std::regex_error がスローされます (C++のみ)

IdentityEscape は任意の非英数字文字にすることができます:例えば、別のバックスラッシュなどです。これは文字をそのままマッチングします。

#include <cstddef>
#include <iostream>
#include <regex>
#include <string>
void show_matches(const std::wstring& in, const std::wstring& re)
{
    std::wsmatch m;
    std::regex_search(in, m, std::wregex(re));
    if (!m.empty())
    {
        std::wcout << L"input=[" << in << L"], regex=[" << re << L"]\n  "
                      L"prefix=[" << m.prefix() << L"]\n  wsmatch: ";
        for (std::size_t n = 0; n < m.size(); ++n)
            std::wcout << L"m[" << n << L"]=[" << m[n] << L"] ";
        std::wcout << L"\n  suffix=[" << m.suffix() << L"]\n";
    }
    else
        std::wcout << L"input=[" << in << "], regex=[" << re << L"]: NO MATCH\n";
}
int main()
{
    // ほとんどのエスケープはC++と同様ですが、メタ文字は除きます。ただし、スラッシュは
    // 二重エスケープするか、生文字列を使用する必要があります。
    show_matches(L"C++\\", LR"(C\+\+\\)");
    // エスケープシーケンスとNUL。
    std::wstring s(L"ab\xff\0cd", 5);
    show_matches(s, L"(\\0|\\u00ff)");
    // ECMAScriptはUTF-16アトムを使用するため、非BMP Unicodeのマッチングは定義されていません。
    // この絵文字のバナナがマッチするかどうかはプラットフォームに依存する可能性があります:
    // これらはワイド文字列である必要があります!
    show_matches(L"\U0001f34c", L"[\\u0000-\\ufffe]+");
}

出力例:

input=[C++\], regex=[C\+\+\\]
  prefix=[]
  wsmatch: m[0]=[C++\]
  suffix=[]
input=[ab?c], regex=[(\0{{!}}\u00ff)]
  prefix=[ab]
  wsmatch: m[0]=[?] m[1]=[?]
  suffix=[c]
input=[?], regex=[[\u0000-\ufffe]+]: NO MATCH

文字クラス

Atomは文字クラスを表すことができ、つまり、事前に定義された文字グループのいずれかに属する文字と一致し、その1文字を消費します。

文字クラスは文字クラスエスケープによって導入できます:

Atom ::

\ 文字クラスエスケープ

または直接

Atom ::

文字クラス

文字クラスエスケープは、以下のように、いくつかの一般的な文字クラスの短縮形です:

CharacterClassEscape ClassName expression (C++ only) 意味
d [[:digit:]] 数字
D [^[:digit:]] 数字以外
s [[:space:]] 空白文字
S [^[:space:]] 空白文字以外
w [_[:alnum:]] 英数字と文字 _
W [^_[:alnum:]] 英数字または _ 以外の文字
C++におけるこれらの文字クラスエスケープの正確な意味は、ECMAScriptのように受け入れ可能な文字を明示的に列挙するのではなく、ロケール依存の名前付き文字クラスによって定義されます。

CharacterClass は、角括弧で囲まれた ClassRanges のシーケンスであり、オプションとして否定演算子 ^ で始まります。もし ^ で始まる場合、この Atom は、すべての ClassRanges の和集合によって表される文字セットに含まれない任意の文字にマッチします。それ以外の場合、この Atom は、すべての ClassRanges の和集合によって表される文字セットに含まれる任意の文字にマッチします。

CharacterClass ::

[ [ lookahead ∉ { ^ }] ClassRanges ]
[ ^ ClassRanges ]

ClassRanges ::

[空]
NonemptyClassRanges

NonemptyClassRanges ::

ClassAtom
ClassAtom NonemptyClassRangesNoDash
ClassAtom - ClassAtom ClassRanges

空でないクラス範囲が ClassAtom - ClassAtom の形式を持つ場合、以下のように定義される範囲の任意の文字にマッチします: (C++のみ)

最初の ClassAtom は単一の照合要素 c1 に一致し、2番目の ClassAtom は単一の照合要素 c2 に一致しなければなりません。入力文字 c がこの範囲に一致するかどうかをテストするには、以下の手順が実行されます:

1) If std::regex_constants::collate is not on, the character is matched by direct comparison of code points: c is matched if c1 <= c && c <= c2
1) それ以外の場合( std::regex_constants::collate が有効な場合):
1) std::regex_constants::icase が有効な場合、3つの文字すべて( c c1 、および c2 )は std::regex_traits::translate_nocase に渡される
2) それ以外の場合( std::regex_constants::icase が設定されていない場合)、3つの文字すべて( c c1 、および c2 )が std::regex_traits::translate に渡される
2) 結果の文字列は std::regex_traits::transform を使用して比較され、文字 c transformed c1 <= transformed c && transformed c <= transformed c2 の場合にマッチします

文字 - は、それが以下の場合にリテラルとして扱われます

  • ClassRanges の最初または最後の文字
  • ダッシュで区切られた範囲指定の先頭または末尾のClassAtom
  • ダッシュで区切られた範囲指定の直後
  • バックスラッシュでエスケープされた CharacterEscape として

NonemptyClassRangesNoDash ::

ClassAtom
ClassAtomNoDash NonemptyClassRangesNoDash
ClassAtomNoDash - ClassAtom ClassRanges

ClassAtom ::

-
ClassAtomNoDash
ClassAtomExClass (C++のみ)
ClassAtomCollatingElement (C++のみ)
ClassAtomEquivalence (C++のみ)

ClassAtomNoDash ::

SourceCharacter ただし、 \ または ] または - を除く
\ ClassEscape

ClassAtomNoDash は単一の文字を表します -- SourceCharacter をそのまま使用するか、以下のようにエスケープします:

ClassEscape ::

DecimalEscape
b
CharacterEscape
CharacterClassEscape

特殊な ClassEscape \b は、コードユニット U+0008(バックスペース)にマッチする文字セットを生成します。 CharacterClass の外側では、単語境界の Assertion となります。

\B の使用および CharacterClass 内での任意の後方参照(ゼロ以外の DecimalEscape )の使用はエラーです。

文字 - および ] は、アトムとして扱われるようにするために、一部の状況ではエスケープが必要な場合があります。 CharacterClass の外側で特別な意味を持つ * ? などの他の文字は、エスケープする必要はありません。

POSIXベースの文字クラス

これらの文字クラスはECMAScript文法への拡張であり、POSIX正規表現で見られる文字クラスと同等です。

ClassAtomExClass (C++ only) ::

[: ClassName :]

名前付き文字クラス ClassName のメンバーであるすべての文字を表します。この名前は、 std::regex_traits::lookup_classname がこの名前に対して非ゼロを返す場合にのみ有効です。 std::regex_traits::lookup_classname で説明されているように、以下の名前は確実に認識されることが保証されています: alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit, d, s, w 。追加の名前は、システム提供のロケール(日本語の jdigit jkanji など)によって提供されるか、ユーザー定義の拡張として実装される場合があります。

ClassAtomCollatingElement (C++のみ) ::

[. ClassName .]

名前付き照合要素を表します。これは、埋め込まれたロケールの下で単一の単位として照合される単一の文字または文字のシーケンスを表すことがあります。例えば、チェコ語における [.tilde.] [.ch.] などです。この名前は、 std::regex_traits::lookup_collatename が空文字列でない場合にのみ有効です。

std::regex_constants::collate を使用する場合、照合要素は常に範囲の終点として使用できます(例:ハンガリー語における [[.dz.]-g] )。

ClassAtomEquivalence (C++ only) ::

[= ClassName =]

指定された照合要素名と同じ等価クラスに属するすべての文字、すなわち、照合要素 ClassName の一次照合キーと同じ一次照合キーを持つすべての文字を表します。この名前は、 std::regex_traits::lookup_collatename がその名前に対して空文字列を返さず、かつ std::regex_traits::transform_primary std::regex_traits::lookup_collatename の呼び出し結果に対して空文字列を返さない場合にのみ有効です。

プライマリソートキーとは、大文字小文字、アクセント、またはロケール固有の調整を無視するものである。例えば、 [[=a=]] は以下の文字のいずれにもマッチする: a, À, Á, Â, Ã, Ä, Å, A, à, á, â, ã, ä and å.

ClassName (C++ only) ::

ClassNameCharacter
ClassNameCharacter ClassName

ClassNameCharacter (C++ only) ::

SourceCharacter ただし、 . = : 以外