C++ regex échapper punctional de caractères comme “.”
Correspondant à un "." dans une chaîne de caractères avec la std::tr1::regex
classe me fait utiliser un drôle de solution de contournement.
Pourquoi ai-je besoin de vérifier les "\\\\." au lieu de "\\."?
regex(".") //Matches everything (but "\n") as expected.
regex("\\.") //Matches everything (but "\n").
regex("\\\\.") //Matches only ".".
Quelqu'un peut-il m'expliquer pourquoi? C'est vraiment me tracasse depuis que j'ai eu mon code écrit à l'aide de boost::regex
des classes, ce qui n'a pas besoin de cette syntaxe.
Edit: Désolé, regex("\\\\.")
semble correspondre à rien.
Edit2: du code
void parser::lex(regex& token)
{
//Skipping whitespaces
{
regex ws("\\s*");
sregex_token_iterator wit(source.begin() + pos, source.end(), ws, regex_constants::match_default), wend;
if(wit != wend)
pos += (*wit).length();
}
sregex_token_iterator it(source.begin() + pos, source.end(), token, regex_constants::match_default), end;
if (it != end)
temp = *it;
else
temp = "";
}
- Quel compilateur et les options du compilateur que vous utilisez?
- Je vois que vous eu le même problème dans la rédaction de votre question que j'ai eu avec ma réponse. <.< c'est pourquoi il a d'abord dit \ et \\, droit?
- Oui, en effet.
- Pour l'avoir testé dans Visual Studio 2012, je n'ai pas le même problème. \\. semble correspondre à "\.", comme il se doit
- Bizarre, peut-être que c'est mon code. J'ai posté la fonction principale.
- laissez-nous continuer cette discussion dans le chat
- Vous savez, la même version de C++ qui est inclus
std::regex
également inclus raw littéraux de chaîne. On pourrait direR":(\.):"
et ne pas avoir à s'échapper tellement -- seulement les choses que la regex lui-même doivent être échappés.
Vous devez vous connecter pour publier un commentaire.
Comme il s'avère, en fait le problème était dû à la façon dont sregex_token_iterator a été utilisé. À l'aide de match_default voulait dire que c'était toujours de trouver le match suivant de la chaîne, le cas échéant, même si il y a un non-match entre les deux. C'est,
donnerait un match à la dot, plutôt que la déclaration qu'il n'y a pas de match.
La solution est d'utiliser match_continuous à la place.
it
ne correspond pasend
depuis la chaîne contient encore des personnages. Ainsi, un simple remplacement deif (it != end)
àif (it != end && *it != "")
fixe tout!C'est parce que
\.
est interprété comme une séquence d'échappement, dont la langue elle-même est d'essayer de l'interpréter comme un seul caractère. Ce que vous voulez pour votre regex pour contenir la chaîne "\.", ce qui est écrit\\.
parce que\\
est la séquence d'échappement pour le caractère barre oblique inverse (\).Essayer d'échapper à la dot par son code ASCII: