Dans les expressions régulières JS, les symboles ^
et $
désignent début et fin de la chaîne . Et seulement avec le modificateur /m
(mode multiligne), ils correspondent à début et fin de ligne - position avant et après CR/LF.
Mais dans std :: regex / Les symboles du mode ECMAscript ^
et $
correspondent début et fin de ligne toujours.
Est-il possible dans std :: regex de définir le début et la fin de la chaîne des points de correspondance? En d'autres termes: supporter le mode JavaScript multiligne ...
Par défaut, le mode ECMAscript traite déjà ^
en début de ligne et début-de-ligne et $
en tant que fin d’entrée et fin de ligne. Il n'y a aucun moyen de les faire correspondre à uniquement début ou à la fin de la saisie, mais il est possible de les faire correspondre à uniquement début ou à la fin de la ligne:
Lors de l'appel de std::regex_match
, std::regex_search
ou std::regex_replace
, il existe un argument de type std::regex_constants::match_flag_type
dont la valeur par défaut est std::regex_constants::match_default
.
^
ne correspond qu'au début de la ligne, spécifiez std::regex_constants::match_not_bol
$
ne correspond qu'à la fin de ligne, spécifiez std::regex_constants::match_not_eol
std::regex_constants::match_not_bol | std::regex_constants::match_not_eol
)^
et indépendamment de la présence de std::regex_constants::match_not_bol
en spécifiant std::regex_constants::match_continuous
Ceci est bien expliqué dans la documentation de grammaire ECMAScript sur cppreference.com , ce que je recommande vivement à cplusplus.com en général.
Avertissement: j'ai testé avec MSVC, Clang + libc ++ et Clang + libstdc ++, et seul MSVC a le comportement correct à l'heure actuelle.
Les ^
et $
correspondent au début et à la fin du string , pas une ligne. Voir cette démo qui ne trouve aucune correspondance dans "1\n2\n3"
avec ^\d+$
regex. Lorsque vous ajoutez des alternatives (voir ci-dessous), il y a 3 correspondances .
std::regex
ne permet pas de faire correspondre les ancres au début/à la fin de la ligne. Vous devez l'imiter avec des alternances:
^ -> (^|\n)
$ -> (?=\n|$)
Notez que $
peut être "émulé" entièrement avec (?=\n|$)
(où vous pouvez ajouter plus de symboles de terminaison de ligne ou de séquences de symboles, comme (?=\r?\n|\r|$)
), mais avec ^
, vous ne pouvez pas trouver une solution de contournement à 100%.
Comme il n'y a pas de support lookbehind, vous devrez peut-être ajuster d'autres parties de votre motif regex à cause de (^|\n)
, comme utiliser la capture de groupes plus souvent qu'avec un support lookbehind.
L'extrait de code suivant correspond aux adresses électroniques commençant par [a-z], suivies de 0 ou 1 point, puis de 0 ou plusieurs lettres a-z, se terminant par "@ gmail.com". Je l'ai testé.
string reg = "^[a-z]+\\.*[a-z]*@gmail\\.com$";
regex reg1(reg, regex_constants::icase);
reg1(regex_str, regex_constants::icase);
string email;
cin>>email;
if (regex_search(email, reg1))