2010-05-26 5 views
2

J'ai un code qui fonctionne depuis presque 4 ans (depuis boost 1.33) et aujourd'hui je suis passé de boost 1.36 à boost 1.42 et maintenant j'ai un problème.Problème avec boost :: find_format_all, boost :: regex_finder et formateur regex personnalisé (bug boost 1.42)

J'appelle un formateur personnalisé sur une chaîne pour formater des parties de la chaîne qui correspondent à un REGEX.

Par exemple, une chaîne comme: "abc, def:" sera remplacé par "abc \ 2Cdef \ 3B" si le REGEX contient "([;:])"

boost::find_format_all(mystring, boost::regex_finder(REGEX), custom_formatter()); 

Le formatter personnalisé ressemble à ceci:

struct custom_formatter() 
{ 

    template< typename T > 
    std::string operator()(const T & s) const 
    { 
     std::string matchStr = s.match_results().str(1); 

     // perform substitutions 

     return matchStr; 
    } 

} 

cela a bien fonctionné, mais avec coup de pouce 1,42 Je sais avoir « non initialisées » (s.match_results) qui donnent à stimuler :: exception_detail :: clone_implINS0 _ :: error_info_injectorISt11logic_errorEEEE - Tentative d'accéder à un uninitialzed boost :: match_results <> clas s. Cela signifie que parfois je suis dans le foncteur pour formater une chaîne mais il n'y a pas de correspondance.

Est-ce que je fais quelque chose de mal? Ou est-ce normal d'entrer dans le foncteur quand il n'y a pas de correspondance et que je devrais vérifier quelque chose? Pour l'instant, ma solution est d'essayer {} catch() {} l'exception et tout fonctionne bien, mais d'une certaine manière cela ne me semble pas très bien.

EDIT1

En fait, j'ai un nouveau match vide à la fin de chaque chaîne pour analyser.

EDIT2: une solution inspirée par ablaeul

template< typename T > 
    std::string operator()(const T & s) const 
    { 

     if(s.begin() == s.end()) return std::string(); 

     std::string matchStr = s.match_results().str(1); 

     // perform substitutions 

     return matchStr; 
    } 

EDIT3 semble être un bogue dans (au moins) 1,42 stimuler

Répondre

2

Le struct find_regexF semble être le coupable. Comme vous pouvez le voir, il retourne un résultat vide avec un match_results() non initialisé. En regardant à travers SO m'a trouvé la solution suivante:

struct custom_formatter() 
{ 

    template< typename T > 
    std::string operator()(const T & s) const 
    { 
     std::string matchStr; 
     for (typename T::const_iterator i = Match.begin(); 
      i != Match.end(); 
      i++) { 
      // perform substitutions via *i 
     } 
     return matchStr; 
    } 

} 

EDIT: regardant comment Boost uses the formatter ici est une autre solution:

template<typename InputIteratorT> 
std::string operator()( 
    const regex_search_result<InputIteratorT>& Replace) const 
{ 
    if (Replace.empty()) 
    { 
     return std::string(); 
    } 
    else 
    { 
     std::string matchStr = s.match_results().str(1); 
     // perform substitutions 
     return matchStr;  
    } 
} 
+0

Le problème est que vous n'avez pas les groupes regex. Chaque itération sur * je vais vous donner un personnage mais vous ne pouvez pas obtenir par exemple le groupe que vous vouliez (avec une regex plus compliquée que je veux dire). Mais je peux juste tester s.begin() == s.end() au début et quitter si c'est le cas. Mais je ne vois pas vraiment pourquoi j'obtiens des résultats vides. – Nikko

+0

Oui, j'ai fait quelque chose comme ça, au moins pour quand j'utilise boost version 1.42, en attendant une correction de bug. Merci pour l'aide. – Nikko