J'essaie d'utiliser std :: regex dans un morceau de code C ++ 11, mais il semble que le support soit un peu bogué. Un exemple:
#include <regex>
#include <iostream>
int main (int argc, const char * argv[]) {
std::regex r("st|mt|tr");
std::cerr << "st|mt|tr" << " matches st? " << std::regex_match("st", r) << std::endl;
std::cerr << "st|mt|tr" << " matches mt? " << std::regex_match("mt", r) << std::endl;
std::cerr << "st|mt|tr" << " matches tr? " << std::regex_match("tr", r) << std::endl;
}
les sorties:
st|mt|tr matches st? 1
st|mt|tr matches mt? 1
st|mt|tr matches tr? 0
une fois compilé avec gcc (MacPorts gcc47 4.7.1_2) 4.7.1, soit avec
g++ *.cc -o test -std=c++11
g++ *.cc -o test -std=c++0x
ou
g++ *.cc -o test -std=gnu++0x
De plus, l'expression régulière fonctionne bien si je n'ai que deux modèles alternatifs, par exemple st|mt
, il semble donc que le dernier ne correspond pas pour certaines raisons. Le code fonctionne bien avec le compilateur Apple LLVM.
Des idées sur la façon de résoudre le problème?
Mettre à jour une solution possible consiste à utiliser des groupes pour implémenter plusieurs alternatives, par exemple (st|mt)|tr
.
<regex>
support de libstdc ++ est incomplet. Que pouvons-nous vous aider?regex
dans libstdc ++, voir gcc.gnu.org/onlinedocs/libstdc++/manual/…<regex>
au cours des 3-4 dernières années (comme dans: il reste non implémenté).<regex>
c'est fourni par libstdc ++ (la bibliothèque standard de GCC) pasgcc
(le frontal du compilateur), il fait partie de GCC (le projet). Voir «libstdc ++ - v3 est développé et publié dans le cadre de GCC» . Si votre distribution choisit de la diviser en un package séparé, cela n'a rien à voir avec GCC.Réponses:
<regex>
a été implémenté et publié dans GCC 4.9.0.Dans votre (ancienne) version de GCC, il n'est pas implémenté .
Ce
<regex>
code prototype a été ajouté lorsque tout le support C ++ 0x de GCC était hautement expérimental, traçant les premières ébauches de C ++ 0x et étant mis à la disposition des utilisateurs. Cela a permis aux gens de trouver des problèmes et de donner leur avis au comité de normalisation avant que la norme ne soit finalisée. À l'époque, beaucoup de gens étaient reconnaissants d'avoir eu accès à des fonctionnalités de pointe bien avant la fin de C ++ 11 et avant que de nombreux autres compilateurs ne fournissent de support, et ces commentaires ont vraiment aidé à améliorer C ++ 11. C'était une bonne chose TM .Le
<regex>
code n'a jamais été dans un état utile, mais a été ajouté en tant que travail en cours, comme beaucoup d'autres bits de code à l'époque. Il a été enregistré et mis à la disposition des autres pour qu'ils collaborent s'ils le voulaient, avec l'intention qu'il soit fini par la suite.C'est souvent ainsi que fonctionne l'open source: Libérez tôt, publiez souvent - malheureusement, dans le cas où
<regex>
nous n'avons eu que la partie initiale correcte et pas la partie souvent qui aurait terminé l'implémentation.La plupart des parties de la bibliothèque étaient plus complètes et sont maintenant presque entièrement implémentées, mais
<regex>
ne l'ont pas été, donc elle est restée dans le même état inachevé depuis son ajout.Ce n'était pas une si mauvaise idée il y a quelques années, lorsque C ++ 0x était encore en cours de travail et que nous avons expédié de nombreuses implémentations partielles. Personne ne pensait qu'il resterait inutilisable aussi longtemps, donc, avec le recul, il aurait peut-être dû être désactivé et nécessiter une macro ou une option intégrée pour l'activer. Mais ce navire a navigué il y a longtemps. Il y a des symboles exportés depuis la bibliothèque libstdc ++. Donc, la bibliothèque qui dépend du code regex, donc simplement le supprimer (par exemple dans GCC 4.8) n'aurait pas été trivial.
la source
Détection des fonctionnalités
Ceci est un extrait de code pour détecter si l'
libstdc++
implémentation est implémentée avec le préprocesseur C définit:Macros
_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
est définie dansbits/regex.tcc
au4.9.x
_GLIBCXX_REGEX_STATE_LIMIT
est définie dansbits/regex_automatron.h
au5+
_GLIBCXX_RELEASE
a été ajouté à7+
la suite de cette réponse et est la version majeure de GCCEssai
Vous pouvez le tester avec GCC comme ceci:
Résultats
Voici quelques résultats pour différents compilateurs:
Voilà des dragons
Ceci n'est pas du tout pris en charge et repose sur la détection des macros privées que les développeurs de GCC ont placées dans les en-
bits/regex*
têtes. Ils pouvaient changer et disparaître à tout moment . Espérons qu'ils ne seront pas supprimés dans les versions actuelles 4.9.x, 5.x, 6.x mais ils pourraient disparaître dans les versions 7.x.Si les développeurs de GCC ajoutaient un
#define _GLIBCXX_HAVE_WORKING_REGEX 1
(ou quelque chose, un indice) dans la version 7.x qui persistait, cet extrait de code pourrait être mis à jour pour inclure cela et les versions ultérieures de GCC fonctionneraient avec l'extrait de code ci-dessus.Autant que je sache, tous les autres compilateurs ont un fonctionnement
<regex>
quand__cplusplus >= 201103L
mais YMMV.De toute évidence, cela serait complètement interrompu si quelqu'un définissait les macros
_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
ou en_GLIBCXX_REGEX_STATE_LIMIT
dehors des en-stdc++-v3
têtes.la source
_GLIBCXX_REGEX_IS_OK_NOW_KTHXBAI
dans les en-têtes, pour ne pas l'oublier - merci!Pour le moment (utiliser std = c ++ 14 dans g ++ (GCC) 4.9.2) n'accepte toujours pas regex_match.
Voici une approche qui fonctionne comme regex_match mais qui utilise à la place sregex_token_iterator. Et cela fonctionne avec g ++.
il imprimera 1 2 3
vous pouvez lire la référence sregex_token_iterator sur: http://en.cppreference.com/w/cpp/regex/regex_token_iterator
la source
std::regex_search
, voir wandbox.org/permlink/rLbGyYcYGNsBWsaB