2 votes

c++0x regex fonctionne avec clang mais pas avec gcc 4.9.2

Je suis en train d'analyser des enregistrements de texte multilignes qui ressemblent à ce qui suit :

> UniRef50_A0A091LJV8 Lysozyme g (Fragment) n=2 Tax=Chlamydotis 
macqueenii RepID=A0A091LJV8_9GRUI
Length=186

 Score =   114 bits (285),  Expect = 3e-30, Method: Compositional matrix adjust.
 Identities = 54/83 (65%), Positives = 65/83 (78%), Gaps = 0/83 (0%)

Query  1   ASCKTAKPEGLSYCGVSASKKIAERDLQAMDRYKTIIKKVGEKLCVEPAVIAGIISRESH  60
       AS  TA+PEGLSY GVSAS+KIAE+DL+ M +++  I +V     V+PA+IAGIISRESH
Sbjct  17  ASEATARPEGLSYAGVSASEKIAEKDLKNMQKHQDKITRVANSKGVDPALIAGIISRESH  76

Query  61  AGKVLKNGWGDRGNGFGLMQVDK  83
            G VL+NGWGD  N FGLMQVDK
Sbjct  77  GGTVLENGWGDHNNAFGLMQVDK  99

J'utilise quelques expressions régulières pour extraire des données de ces enregistrements. Elles fonctionnent toutes lorsqu'elles sont compilées avec clang (MacOS X) et gcc 4.9.2 (Ubuntu). L'une d'entre elles cependant lance un regex_error lorsqu'il est compilé avec gcc. Voici l'exemple minimal (non) fonctionnel :

#include <regex>

const std::string regex_string_OK_1 = "\\[(.+?)\\]";
const std::string regex_string_OK_2 = "Tax\\s*?=\\s*?([\\n\\w ]*?)\\s*?RepID";
const std::string regex_string_PROBLEM = "Query\\s+?(\\d+?)\\s+?([_\\-[:alnum:]]+?)\\s+?(\\d+?)\\n.+?\\nSbjct\\s+?(\\d+?)\\s+?([_\\-[:alnum:]]+?)\\s+?(\\d+?)\\n";

int main(int argc, const char *argv[]) {

std::regex regex_OK_1(regex_string_OK_1);
std::regex regex_OK_2(regex_string_OK_2);

std::regex regex_PROBLEM(regex_string_PROBLEM); // This line throws regex_error on Ubuntu

  return 0;
}

J'ai testé toutes les chaînes de regex avec https://myregextester.com Ils fonctionnent très bien. De plus, le code compilé sur MacOS avec clang analyse sans problème de nombreuses données réelles. Mais je dois maintenant exécuter le code sur un système Linux/gcc.

2voto

marcin_j Points 12237

J'ai dû complètement rééditer cette réponse, car j'ai testé sur http://melpon.org/wandbox/ de votre code sous clang et gcc dans différentes versions, je commence à penser que gcc ne reconnait pas \- comme un échappement valide pour le trait d'union (en fait dans toutes les versions).

Votre exemple me semble maintenant correct : [_\\-[:alnum:]] contient déjà un échappement pour le trait d'union : \\- mais pour certaines raisons, gcc ne l'aime pas. Je suggère donc la classe de caractères suivante :

 `[-_[:alnum:]]`

si vous avez besoin de faire correspondre également la barre oblique : \ vous devez alors ajouter \\\\ (J'ai supposé précédemment que c'était votre intention).

ps. ma réponse précédente est restée \\ qui, d'un autre côté, a causé des exceptions sur clang, mais c'était une regexp incorrecte car elle se terminait par un crochet d'échappement : \[ ce qui était un non-sens - mais pourquoi pas sur gcc ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X