Regex C ++: extraire une sous-chaîne

Je voudrais extraire une sous-chaîne entre deux autres.
ex: /home/toto/FILE_mysymbol_EVENT.DAT
ou simplement FILE_othersymbol_EVENT.DAT
Et j’aimerais avoir: mysymbol et othersymbol

Je ne veux pas utiliser boost ou d’autres libs. Juste des éléments standard de C ++, à l’exception de la version ROOT du CERN, avec TRegexp , mais je ne sais pas comment l’utiliser …

Depuis l’année dernière, C ++ a une expression régulière intégrée à la norme. Ce programme montrera comment les utiliser pour extraire la chaîne que vous recherchez:

 #include  #include  int main() { const std::ssortingng s = "/home/toto/FILE_mysymbol_EVENT.DAT"; std::regex rgx(".*FILE_(\\w+)_EVENT\\.DAT.*"); std::smatch match; if (std::regex_search(s.begin(), s.end(), match, rgx)) std::cout << "match: " << match[1] << '\n'; } 

Il produira:

 match: mysymbol

Il convient toutefois de noter que cela ne fonctionnera pas dans GCC car sa bibliothèque ne prend pas en charge les expressions rationnelles. Fonctionne bien dans VS2010 (et probablement VS2012) et devrait fonctionner en clair.


À l'heure actuelle (fin 2016), tous les compilateurs C ++ modernes et leurs bibliothèques standard sont parfaitement à jour avec le standard C ++ 11, ainsi que la plupart, sinon tous, de C ++ 14. GCC 6 et le futur Clang 4 prennent également en charge la plupart des normes C ++ 17 à venir.

TRegexp ne prend en charge qu’un sous-ensemble très limité d’expressions régulières par rapport aux autres versions de regex. Cela rend la construction d’une seule expression rationnelle adaptée à vos besoins quelque peu délicate.

Une solution possible:

 [^_]*_([^_]*)_ 

correspondra à la chaîne jusqu’au premier trait de soulignement, puis capturera tous les caractères jusqu’au trait de soulignement suivant. Le résultat pertinent de la correspondance est ensuite trouvé dans le groupe numéro 1.

Mais dans votre cas, pourquoi utiliser une regex? Il vous suffit de rechercher les première et deuxième occurrences de votre délimiteur _ dans la chaîne et d’extraire les caractères entre ces positions.

Si vous voulez utiliser des expressions régulières, je vous recommande vraiment d’utiliser les expressions rationnelles de C ++ 11 ou, si vous avez un compilateur qui ne les prend pas encore en charge, Boost. Boost est quelque chose que je considère presque comme faisant partie de la norme C ++.

Mais pour cette question particulière, vous n’avez vraiment besoin d’aucune forme d’expression régulière. Quelque chose comme cette esquisse devrait bien fonctionner, après avoir ajouté toutes les vérifications d’erreur appropriées ( beg != npos , end != npos etc.), tester le code et supprimer mes fautes de frappe:

 std::ssortingng between(std::ssortingng const &in, std::ssortingng const &before, std::ssortingng const &after) { size_type beg = in.find(before); beg += before.size(); size_type end = in.find(after, beg); return in.substr(beg, end-beg); } 

De toute évidence, vous pouvez changer le paramètre std::ssortingng en un paramètre de modèle et il devrait également fonctionner parfaitement avec std::wssortingng ou les instanciations plus rarement utilisées de std::basic_ssortingng .