Namespaces
Variants

Modified ECMAScript regular expression grammar

From cppreference.net

Cette page décrit la grammaire des expressions régulières utilisée lorsque std::basic_regex est construit avec syntax_option_type défini sur ECMAScript (valeur par défaut). Consultez syntax_option_type pour les autres grammaires d'expressions régulières prises en charge.

La grammaire d'expressions régulières ECMAScript 3 en C++ est la grammaire ECMA-262 avec des modifications marquées (C++ uniquement) ci-dessous.

Table des matières

Vue d'ensemble

La grammaire d'expression régulière modifiée est principalement la grammaire ECMAScript RegExp avec une extension de type POSIX sur les locales sous ClassAtom . Quelques clarifications sur les vérifications d'égalité et l'analyse des nombres sont apportées. Pour plusieurs des exemples ici, vous pouvez essayer cet équivalent dans la console de votre navigateur :

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

Les « références normatives » dans la norme spécifient ECMAScript 3. Nous établissons un lien vers la spécification ECMAScript 5.1 ici car il s'agit d'une version ne présentant que des modifications mineures par rapport à ECMAScript 3, et elle dispose également d'une version HTML. Consultez le Guide MDN sur les expressions régulières JavaScript pour un aperçu des fonctionnalités du dialecte.

Alternatives

Un motif d'expression régulière est une séquence d'une ou plusieurs Alternatives , séparées par l'opérateur de disjonction | (en d'autres termes, l'opérateur de disjonction a la priorité la plus faible).

Pattern ::

Disjonction

Disjonction ::

Alternative
Alternative | Disjonction

Le modèle essaie d'abord de sauter la Disjunction et de faire correspondre l' Alternative gauche suivie du reste de l'expression régulière (après la Disjunction).

En cas d'échec, il tente d'ignorer l' Alternative de gauche et de faire correspondre la Disjonction de droite (suivie du reste de l'expression régulière).

Si l' Alternative de gauche, la Disjonction de droite et le reste de l'expression rationnelle ont tous des points de choix, tous les choix dans le reste de l'expression sont essayés avant de passer au choix suivant dans l' Alternative de gauche. Si les choix dans l' Alternative de gauche sont épuisés, la Disjonction de droite est essayée à la place de l' Alternative de gauche.

Toute parenthèse capturante à l'intérieur d'une Alternative ignorée produit des sous-correspondances vides.

#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"); // Alternative gauche correspond en premier
    // La correspondance de l'entrée avec l'Alternative gauche (a) suivie
    // par le reste de l'expression régulière (c|bc) réussit, ce qui résulte
    // en m[1]="a" et m[4]="bc".
    // Les Alternatives ignorées (ab) et (c) laissent leurs sous-correspondances
    // m[3] et m[5] vides.
    show_matches("abc", "((a)|(ab))((c)|(bc))");
}

Sortie :

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=[]

Termes

Chaque Alternative est soit vide, soit une séquence de Term s (sans séparateurs entre les Term s)

Alternative ::

[vide]
Terme Alternatif

Vide Alternative correspond toujours et ne consomme aucune entrée.

Les Termes consécutifs tentent de correspondre simultanément à des portions consécutives de l'entrée.

Si l' Alternative gauche, le Term droit et le reste de l'expression régulière ont tous des points de choix, tous les choix dans le reste de l'expression sont essayés avant de passer au choix suivant dans le Term droit, et tous les choix dans le Term droit sont essayés avant de passer au choix suivant dans l' Alternative gauche.

#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", ""); // une expression régulière vide est une Alternative vide unique
    show_matches("abc", "abc|"); // l'Alternative de gauche est d'abord correspondante
    show_matches("abc", "|abc"); // l'Alternative de gauche est d'abord correspondante, laissant abc non correspondant
}

Sortie :

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]

Quantificateurs

  • Chaque Terme est soit une Assertion (voir ci-dessous), soit un Atome (voir ci-dessous), soit un Atome immédiatement suivi d'un Quantificateur

Term ::

Assertion
Atome
Atome Quantificateur

Chaque Quantificateur est soit un quantificateur gourmand (qui consiste en un seul PréfixeDeQuantificateur ) soit un quantificateur non gourmand (qui consiste en un PréfixeDeQuantificateur suivi du point d'interrogation ? ).

Quantificateur ::

Préfixe de quantificateur
Préfixe de quantificateur ?

Chaque QuantifierPrefix détermine deux nombres : le nombre minimum de répétitions et le nombre maximum de répétitions, comme suit :

QuantificateurPréfixe Minimum Maximum
* zéro infini
+ un infini
? zéro un
{ DecimalDigits } valeur de DecimalDigits valeur de DecimalDigits
{ DecimalDigits , } valeur de DecimalDigits infini
{ DecimalDigits , DecimalDigits } valeur de DecimalDigits avant la virgule valeur de DecimalDigits après la virgule

Les valeurs des DecimalDigits individuels sont obtenues en appelant std::regex_traits::value (C++ uniquement) sur chacun des chiffres.

Un Atom suivi d'un Quantifier est répété le nombre de fois spécifié par le Quantifier . Un Quantifier peut être non-greedy , auquel cas le motif Atom est répété aussi peu de fois que possible tout en correspondant au reste de l'expression régulière, ou il peut être greedy , auquel cas le motif Atom est répété autant de fois que possible tout en correspondant au reste de l'expression régulière.

Le Atom est ce qui est répété, et non l'entrée qu'il correspond, de sorte que différentes répétitions de l' Atom peuvent correspondre à différentes sous-chaînes d'entrée.

Si l' Atom et le reste de l'expression régulière ont tous des points de choix, l' Atom est d'abord mis en correspondance autant de fois (ou aussi peu, si non-greedy ) que possible. Tous les choix dans le reste de l'expression régulière sont essayés avant de passer au choix suivant dans la dernière répétition de l' Atom . Tous les choix dans la dernière (nième) répétition de l' Atom sont essayés avant de passer au choix suivant dans l'avant-dernière (n–1)ième répétition de l' Atom ; à ce moment, il peut s'avérer que plus ou moins de répétitions de l' Atom sont maintenant possibles ; celles-ci sont épuisées (à nouveau, en commençant par soit aussi peu soit autant que possible) avant de passer au choix suivant dans la (n-1)ième répétition de l' Atom et ainsi de suite.

Les captures de l' Atom' sont effacées à chaque fois qu'il est répété (voir l'exemple "(z)((a+)?(b+)?(c))*" ci-dessous)

#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()
{
    // correspondance gourmande, répète [a-z] 4 fois
    show_matches("abcdefghi", "a[a-z]{2,4}");
    // correspondance non gourmande, répète [a-z] 2 fois
    show_matches("abcdefghi", "a[a-z]{2,4}?");
    // L'ordre des points de choix pour les quantificateurs résulte en une correspondance
    // avec deux répétitions, la première correspondant à la sous-chaîne "aa",
    // la seconde correspondant à la sous-chaîne "ba", laissant "ac" non correspondant
    // ("ba" apparaît dans la clause de capture m[1])
    show_matches("aabaac", "(aa|aabaac|ba|b|c)*");
    // L'ordre des points de choix pour les quantificateurs fait que cette regex
    // calcule le plus grand commun diviseur entre 10 et 15
    // (la réponse est 5, et elle remplit m[1] avec "aaaaa")
    show_matches("aaaaaaaaaa,aaaaaaaaaaaaaaa", "^(a+)\\1*,\\1+$");
    // la sous-chaîne "bbb" n'apparaît pas dans la clause de capture m[4]
    // car elle est effacée lorsque la seconde répétition de l'atome
    // (a+)?(b+)?(c) correspond à la sous-chaîne "ac"
    // NOTE : gcc se trompe ici - il n'efface pas correctement le
    // groupe de capture matches[4] comme requis par ECMA-262 21.2.2.5.1,
    // et capture donc incorrectement "bbb" pour ce groupe.
    show_matches("zaacbbbcac", "(z)((a+)?(b+)?(c))*");
}

Sortie :

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=[]

Assertions

Assertion s correspond à des conditions, plutôt qu'à des sous-chaînes de la chaîne d'entrée. Elles ne consomment jamais aucun caractère de l'entrée. Chaque Assertion est l'une des suivantes

Assertion ::

^
$
\ b
\ B
( ? = Disjonction )
( ? ! Disjonction )

L'assertion ^ (début de ligne) correspond

1) La position qui suit immédiatement un caractère LineTerminator (cela peut ne pas être pris en charge) (jusqu'à C++17) (cela n'est garanti que si std::regex_constants::multiline (C++ uniquement) est activé) (depuis C++17)
2) Le début de l'entrée (sauf si std::regex_constants::match_not_bol (C++ only) est activé)

L'assertion $ (fin de ligne) correspond

1) La position d'un caractère LineTerminator (cela peut ne pas être pris en charge) (jusqu'à C++17) (cela n'est garanti que si std::regex_constants::multiline (C++ uniquement) est activé) (depuis C++17)
2) La fin de l'entrée (sauf si std::regex_constants::match_not_eol (C++ uniquement) est activé)

Dans les deux assertions ci-dessus et dans l'atome . ci-dessous, LineTerminator est l'un des quatre caractères suivants : U+000A ( \n ou saut de ligne), U+000D ( \r ou retour chariot), U+2028 (séparateur de ligne), ou U+2029 (séparateur de paragraphe)

L'assertion \b (limite de mot) correspond

1) Le début d'un mot (le caractère actuel est une lettre, un chiffre ou un souligné, et le caractère précédent ne l'est pas)
2) La fin d'un mot (le caractère actuel n'est pas une lettre, un chiffre ou un soulignement, et le caractère précédent est l'un de ceux-ci)
3) Le début de l'entrée si le premier caractère est une lettre, un chiffre ou un tiret bas (sauf si std::regex_constants::match_not_bow (C++ uniquement) est activé)
4) La fin de l'entrée si le dernier caractère est une lettre, un chiffre ou un tiret bas (sauf si std::regex_constants::match_not_eow (C++ uniquement) est activé)

L'assertion \B (limite de mot négative) correspond à tout SAUF ce qui suit

1) Le début d'un mot (le caractère actuel est une lettre, un chiffre ou un souligné, et le caractère précédent n'est pas l'un de ceux-ci ou n'existe pas)
2) La fin d'un mot (le caractère actuel n'est pas une lettre, un chiffre ou un soulignement (ou le matcher est à la fin de l'entrée), et le caractère précédent est l'un de ceux-ci)

L'assertion ( ? = Disjunction ) (prédiction positive de largeur nulle) correspond si Disjunction correspondrait à l'entrée à la position actuelle

L'assertion ( ? ! Disjunction ) (test négatif de largeur nulle) correspond si Disjunction ne correspondrait PAS à l'entrée à la position actuelle.

Pour les deux assertions de prévision, lors de la correspondance du Disjunction , la position n'est pas avancée avant de correspondre au reste de l'expression régulière. De plus, si le Disjunction peut correspondre à la position actuelle de plusieurs manières, seule la première est essayée.

ECMAScript interdit le retour en arrière dans les Disjonctions de regard avant, ce qui affecte le comportement des références arrière vers un regard avant positif depuis le reste de l'expression régulière (voir l'exemple ci-dessous). Les références arrière vers le regard avant négatif depuis le reste de l'expression régulière sont toujours indéfinies (puisque la Disjonction de regard avant doit échouer pour poursuivre).

Note : Les assertions d'anticipation peuvent être utilisées pour créer un ET logique entre plusieurs expressions régulières (voir l'exemple ci-dessous).

#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 << "]: AUCUNE CORRESPONDANCE\n";
}
int main()
{
    // correspond au a à la fin de l'entrée
    show_matches("aaa", "a$");
    // correspond au o à la fin du premier mot
    show_matches("moo goo gai pan", "o\\b");
    // la vérification avant correspond à la chaîne vide immédiatement après le premier b
    // cela remplit m[1] avec "aaa" bien que m[0] soit vide
    show_matches("baaabac", "(?=(a+))");
    // car le retour arrière dans les vérifications avant est interdit,
    // cela correspond à aba plutôt qu'à aaaba
    show_matches("baaabac", "(?=(a+))a*b\\1");
    // ET logique via vérification avant : ce mot de passe correspond SI il contient
    // au moins une lettre minuscule
    // ET au moins une lettre majuscule
    // ET au moins un caractère de ponctuation
    // ET fait au moins 6 caractères de long
    show_matches("abcdef", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}");
    show_matches("aB,def", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}");
}

Sortie :

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,}]: AUCUNE CORRESPONDANCE
input=[aB,def], regex=[(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}]
  prefix=[]
  smatch: m[0]=[aB,def] 
  suffix=[]

Atomes

Un Atom peut être l'un des éléments suivants :

Atom ::

CaractèreDeModèle
.
\ ÉchappementAtome
ClasseDeCaractères
( Disjonction )
( ? : Disjonction )

AtomEscape ::

ÉchappementDécimal
ÉchappementDeCaractère
ÉchappementDeClasseDeCaractères

Les différents types d'atomes s'évaluent différemment.

Sous-expressions

L' Atome ( Disjonction ) est une sous-expression marquée : il exécute la Disjonction et stocke la copie de la sous-chaîne d'entrée qui a été consommée par la Disjonction dans le tableau de sous-correspondances à l'index qui correspond au nombre de fois que la parenthèse ouvrante ( des sous-expressions marquées a été rencontrée dans l'expression régulière entière à ce stade.

En plus d'être retournés dans le std::match_results , les sous-correspondances capturées sont accessibles sous forme de références arrière ( \1 , \2 , ...) et peuvent être référencées dans les expressions régulières. Notez que std::regex_replace utilise $ au lieu de \ pour les références arrière ( $1 , $2 , ...) de la même manière que String.prototype.replace (ECMA-262, partie 15.5.4.11).

L' Atom ( ? : Disjunction ) (sous-expression non capturante) évalue simplement la Disjunction et ne stocke pas ses résultats dans la sous-correspondance. Il s'agit d'un regroupement purement lexical.

Références arrière

DecimalEscape ::

DecimalIntegerLiteral [ lookahead DecimalDigit ]

Si \ est suivi d'un nombre décimal N dont le premier chiffre n'est pas 0 , alors la séquence d'échappement est considérée comme une référence arrière . La valeur N est obtenue en appelant std::regex_traits::value (C++ uniquement) sur chaque chiffre et en combinant leurs résultats en utilisant l'arithmétique en base 10. C'est une erreur si N est supérieur au nombre total de parenthèses de capture gauches dans l'expression régulière entière.

Lorsqu'une référence arrière \N apparaît comme un Atome , elle correspond à la même sous-chaîne que celle actuellement stockée dans le N'ième élément du tableau de sous-correspondance.

L'échappement décimal \0 n'est PAS une référence arrière : c'est un échappement de caractère qui représente le NUL caractère. Il ne peut pas être suivi d'un chiffre décimal.

Comme indiqué précédemment, notez que std::regex_replace utilise $ au lieu de \ pour les références arrière ( $1 , $2 , ...).

Correspondances de caractères uniques

L' Atome . correspond et consomme n'importe quel caractère de la chaîne d'entrée à l'exception d'un TerminateurDeLigne ( U+000D , U+000A , U+2029 , ou U+2028 )

Le Atom PatternCharacter , où PatternCharacter est un SourceCharacter quelconque SAUF les caractères ^ $ \ . * + ? ( ) [ ] { } | , correspond et consomme un caractère de l'entrée s'il est égal à ce PatternCharacter .

L'égalité pour ceci et toutes les autres correspondances de caractères uniques est définie comme suit :

1) Si std::regex_constants::icase est défini, les caractères sont égaux si les valeurs de retour de std::regex_traits::translate_nocase sont égales (C++ uniquement) .
2) Sinon, si std::regex_constants::collate est défini, les caractères sont égaux si les valeurs de retour de std::regex_traits::translate sont égales (C++ uniquement) .
3) Sinon, les caractères sont égaux si operator == renvoie true .

Chaque Atome qui consiste en le caractère d'échappement \ suivi d'un ÉchappementDeCaractère ainsi que l'ÉchappementDécimal spécial \0 , correspond et consomme un caractère de l'entrée s'il est égal au caractère représenté par l' ÉchappementDeCaractère . Les séquences d'échappement de caractères suivantes sont reconnues :

CharacterEscape ::

ControlEscape
c ControlLetter
HexEscapeSequence
UnicodeEscapeSequence
IdentityEscape

Ici, ControlEscape est l'un des cinq caractères suivants : f n r t v

ControlEscape Code Unit Nom
f U+000C saut de page
n U+000A nouvelle ligne
r U+000D retour chariot
t U+0009 tabulation horizontale
v U+000B tabulation verticale

ControlLetter est toute lettre ASCII minuscule ou majuscule et cette séquence d'échappement correspond au caractère dont l'unité de code est égale au reste de la division de la valeur de l'unité de code de ControlLetter par 32 . Par exemple, \cD et \cd correspondent tous deux à l'unité de code U+0004 (EOT) car 'D' est U+0044 et 0x44 % 32 == 4 , et 'd' est U+0064 et 0x64 % 32 == 4 .

HexEscapeSequence est la lettre x suivie d'exactement deux HexDigit s (où HexDigit est l'un des 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F ). Cette séquence d'échappement correspond au caractère dont l'unité de code est égale à la valeur numérique du nombre hexadécimal à deux chiffres.

UnicodeEscapeSequence est la lettre u suivie d'exactement quatre HexDigit s. Cette séquence d'échappement correspond au caractère dont l'unité de code est égale à la valeur numérique de ce nombre hexadécimal à quatre chiffres. Si la valeur ne correspond pas au std::basic_regex 's CharT , std::regex_error est levée (C++ uniquement) .

IdentityEscape peut être n'importe quel caractère non alphanumérique : par exemple, une autre barre oblique inverse. Il correspond au caractère tel quel.

#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()
{
    // La plupart des échappements sont similaires au C++, sauf pour les métacaractères. Vous devrez
    // double-échapper ou utiliser des chaînes brutes pour les barres obliques inverses.
    show_matches(L"C++\\", LR"(C\+\+\\)");
    // Séquences d'échappement et NUL.
    std::wstring s(L"ab\xff\0cd", 5);
    show_matches(s, L"(\\0|\\u00ff)");
    // Aucune correspondance pour Unicode non-BMP n'est définie, car ECMAScript utilise
    // des atomes UTF-16. Le fait que cet emoji banane corresponde peut dépendre de la plateforme :
    // Ceux-ci doivent être des chaînes larges !
    show_matches(L"\U0001f34c", L"[\\u0000-\\ufffe]+");
}

Sortie possible :

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

Classes de caractères

Un Atome peut représenter une classe de caractères, c'est-à-dire qu'il correspondra et consommera un caractère s'il appartient à l'un des groupes prédéfinis de caractères.

Une classe de caractères peut être introduite par une séquence d'échappement de classe de caractères :

Atom ::

\ ÉchappementDeClasseDeCaractères

ou directement

Atom ::

ClasseDeCaractères

Les échappements de classes de caractères sont des raccourcis pour certaines des classes de caractères courantes, comme suit :

Échappement de classe de caractères Expression de nom de classe (C++ uniquement) Signification
d [[:digit:]] chiffres
D [^[:digit:]] non-chiffres
s [[:space:]] caractères d'espacement
S [^[:space:]] caractères non-espacement
w [_[:alnum:]] caractères alphanumériques et le caractère _
W [^_[:alnum:]] caractères autres qu'alphanumériques ou _
La signification exacte de chacune de ces échappements de classe de caractères en C++ est définie en termes des classes de caractères nommées dépendantes de la locale, et non par une liste explicite des caractères acceptables comme dans ECMAScript.

Une CharacterClass est une séquence entre crochets de ClassRanges , commençant optionnellement par l'opérateur de négation ^ . Si elle commence par ^ , cet Atom correspond à tout caractère qui N'EST PAS dans l'ensemble des caractères représentés par l'union de tous les ClassRanges . Sinon, cet Atom correspond à tout caractère qui EST dans l'ensemble des caractères représentés par l'union de tous les ClassRanges .

CharacterClass ::

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

ClassRanges ::

[vide]
NonemptyClassRanges

NonemptyClassRanges ::

ClassAtom
ClassAtom NonemptyClassRangesNoDash
ClassAtom - ClassAtom ClassRanges
**Note:** Le texte a été laissé en anglais conformément aux instructions de ne pas traduire les termes spécifiques au C++ et le texte contenu dans les balises HTML. La structure et le formatage HTML ont été préservés intacts.

Si une plage de classe non vide a la forme ClassAtom - ClassAtom , elle correspond à tout caractère d'une plage définie comme suit : (C++ uniquement)

Le premier ClassAtom doit correspondre à un élément de collation unique c1 et le second ClassAtom doit correspondre à un élément de collation unique c2 . Pour tester si le caractère d'entrée c est reconnu par cette plage, les étapes suivantes sont suivies :

1) Si std::regex_constants::collate n'est pas activé, le caractère est comparé par comparaison directe des points de code : c est correspondant si c1 <= c && c <= c2
1) Sinon (si std::regex_constants::collate est activé) :
1) Si std::regex_constants::icase est activé, les trois caractères ( c , c1 , et c2 ) sont passés à std::regex_traits::translate_nocase
2) Sinon (si std::regex_constants::icase n'est pas défini), les trois caractères ( c , c1 , et c2 ) sont passés à std::regex_traits::translate
2) Les chaînes résultantes sont comparées en utilisant std::regex_traits::transform et le caractère c est correspondant si transformed c1 <= transformed c && transformed c <= transformed c2

Le caractère - est traité littéralement s'il est

  • le premier ou dernier caractère de ClassRanges
  • le ClassAtom de début ou de fin d'une spécification de plage séparée par un tiret
  • suit immédiatement une spécification de plage séparée par un tiret.
  • échappé avec une barre oblique inverse en tant que CharacterEscape

NonemptyClassRangesNoDash ::

ClassAtom
ClassAtomNoDash NonemptyClassRangesNoDash
ClassAtomNoDash - ClassAtom ClassRanges

ClassAtom ::

-
ClassAtomNoDash
ClassAtomExClass (C++ uniquement)
ClassAtomCollatingElement (C++ uniquement)
ClassAtomEquivalence (C++ uniquement)

ClassAtomNoDash ::

SourceCharacter mais pas l'un des \ ou ] ou -
\ ClassEscape

Chaque ClassAtomNoDash représente un seul caractère -- soit SourceCharacter tel quel, soit échappé comme suit :

ClassEscape ::

ÉchappementDécimal
b
ÉchappementCaractère
ÉchappementClasseCaractère

Le caractère spécial ClassEscape \b produit un ensemble de caractères qui correspond à l'unité de code U+0008 (retour arrière). En dehors d'une CharacterClass , il s'agit de l' Assertion de limite de mot.

L'utilisation de \B et l'utilisation de toute référence arrière ( DecimalEscape autre que zéro) à l'intérieur d'une CharacterClass constitue une erreur.

Les caractères - et ] peuvent nécessiter d'être échappés dans certaines situations pour être traités comme des atomes. D'autres caractères ayant une signification spéciale en dehors de CharacterClass , tels que * ou ? , ne nécessitent pas d'être échappés.

Classes de caractères basées sur POSIX

Ces classes de caractères sont une extension de la grammaire ECMAScript, et sont équivalentes aux classes de caractères trouvées dans les expressions régulières POSIX.

ClassAtomExClass (C++ uniquement) ::

[: ClassName :]

Représente tous les caractères qui sont membres de la classe de caractères nommée ClassName . Le nom n'est valide que si std::regex_traits::lookup_classname retourne une valeur non nulle pour ce nom. Comme décrit dans std::regex_traits::lookup_classname , les noms suivants sont garantis d'être reconnus : alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit, d, s, w . Des noms supplémentaires peuvent être fournis par les locales du système (tels que jdigit ou jkanji en japonais) ou implémentés comme une extension définie par l'utilisateur.

ClassAtomCollatingElement (C++ uniquement) ::

[. ClassName .]

Représente l'élément de collation nommé, qui peut représenter un caractère unique ou une séquence de caractères qui se collationnent comme une unité unique sous la locale imbriquée, tel que [.tilde.] ou [.ch.] en tchèque. Le nom n'est valide que si std::regex_traits::lookup_collatename n'est pas une chaîne vide.

Lors de l'utilisation de std::regex_constants::collate , les éléments de collationnement peuvent toujours être utilisés comme points de délimitation d'un intervalle (par exemple [[.dz.]-g] en hongrois).

ClassAtomEquivalence (C++ uniquement) ::

[= ClassName =]

Représente tous les caractères qui sont membres de la même classe d'équivalence que l'élément de collation nommé, c'est-à-dire tous les caractères dont la clé de collation primaire est identique à celle de l'élément de collation ClassName . Le nom n'est valide que si std::regex_traits::lookup_collatename pour ce nom n'est pas une chaîne vide et si la valeur retournée par std::regex_traits::transform_primary pour le résultat de l'appel à std::regex_traits::lookup_collatename n'est pas une chaîne vide.

Une clé de tri primaire est celle qui ignore la casse, l'accentuation ou les adaptations spécifiques aux paramètres régionaux ; ainsi par exemple [[=a=]] correspond à l'un des caractères : a, À, Á, Â, Ã, Ä, Å, A, à, á, â, ã, ä and å.

ClassName (C++ uniquement) ::

CaractèreNomClasse
CaractèreNomClasse NomClasse

ClassNameCharacter (C++ uniquement) ::

SourceCharacter mais pas l'un des . = :