2009-08-12 9 views
3

Je viens de commencer à utiliser Boost :: regex aujourd'hui et je suis assez novice dans les expressions régulières. J'ai utilisé "The Regulator" et Expresso pour tester mon regex et sembler satisfait de ce que je vois là-bas, mais le transfert de cette regex pour booster, ne semble pas faire ce que je veux qu'il fasse. Toute indication pour m'aider à trouver une solution serait la bienvenue. En tant que question secondaire, y at-il des outils qui pourraient m'aider à tester mon regex contre boost.regex?Boost regex ne fonctionne pas comme prévu dans mon code

using namespace boost; 
using namespace std; 

vector<string> tokenizer::to_vector_int(const string s) 
{ 
    regex re("\\d*"); 
    vector<string> vs; 
    cmatch matches; 
    if(regex_match(s.c_str(), matches, re)) { 
     MessageBox(NULL, L"Hmmm", L"", MB_OK); // it never gets here 
     for(unsigned int i = 1 ; i < matches.size() ; ++i) { 
      string match(matches[i].first, matches[i].second); 
      vs.push_back(match); 
     } 
    } 
    return vs; 
} 

void _uttokenizer::test_to_vector_int() 
{ 
    vector<string> __vi = tokenizer::to_vector_int("0<br/>1"); 
    for(int i = 0 ; i < __vi.size() ; ++i) INFO(__vi[i]); 
    CPPUNIT_ASSERT_EQUAL(2, (int)__vi.size());//always fails 
} 

Mise à jour (Merci à Dav pour me aider préciser ma question): J'espérais obtenir un vecteur avec 2 chaînes en eux => "0" et "1". Au lieu de cela, je n'obtiens jamais de succès avec regex_match() (regex_match() renvoie toujours false) donc le vecteur est toujours vide.

Merci '1800 INFORMATION' pour vos suggestions. La méthode to_vector_int() ressemble maintenant à ceci, mais elle entre dans une boucle sans fin (j'ai pris le code que vous avez donné et l'ai modifié pour la rendre compilable) et trouve "0", "", "", "" et ainsi de suite. Il ne trouve jamais le "1".

vector<string> tokenizer::to_vector_int(const string s) 
{ 
    regex re("(\\d*)"); 
    vector<string> vs; 

    cmatch matches; 

    char * loc = const_cast<char *>(s.c_str()); 
    while(regex_search(loc, matches, re)) { 
     vs.push_back(string(matches[0].first, matches[0].second)); 
     loc = const_cast<char *>(matches.suffix().str().c_str()); 
    } 

    return vs; 
} 

En toute honnêteté, je ne pense pas avoir encore compris les bases de la recherche d'un motif et de l'obtention des correspondances. Y a-t-il des tutoriels avec des exemples qui l'expliquent?

+0

Il serait utile que vous expliquiez exactement ce qui ne fonctionnait pas comme prévu - quels résultats obtenez-vous, qu'attendez-vous? – Amber

+0

Merci Dav. J'espère avoir ajouté suffisamment d'informations à ma question. – ossandcad

Répondre

9

Le problème fondamental est que vous utilisez regex_match lorsque vous devez utiliser regex_search:

Les algorithmes regex_search et regex_match faire usage de match_results pour signaler ce qui correspond; la différence entre ces algorithmes est que regex_match ne trouver des correspondances qui consomment tout le texte d'entrée, où que regex_search recherchera un match partout dans le texte étant apparié.

From the boost documentation. Changez-le pour utiliser regex_search et cela fonctionnera.

De même, il semblerait que vous ne capturiez pas les correspondances. Essayez de changer le regex à ceci:

regex re("(\\d*)"); 

Ou, vous devez peut-être être appeler à plusieurs reprises regex_search:

char *where = s.c_str(); 
while (regex_search(s.c_str(), matches, re)) 
{ 
    where = m.suffix().first; 
} 

Ceci est, puisque vous avez seulement une capture dans votre regex.

Vous pouvez également changer votre regex, si vous connaissez la structure de base des données:

regex re("(\\d+).*?(\\d+)"); 

Cela renverrait deux numéros dans la chaîne de recherche.

Notez que l'expression régulière \ d * correspondra à zéro chiffre ou plus - ceci inclut la chaîne vide "" puisque c'est exactement zéro chiffre. Je voudrais changer l'expression à \ d + qui correspondra à 1 ou plus.

+0

Génial.Merci 1800 INFORMATIONS. Je ne savais pas à quel point j'étais dans boost.regex. (Dans ma défense "The Regulator" et Expresso me donnent des résultats positifs en réponse à "Match", donc j'ai affiné dans une méthode nommée similaire dans boost.regex.) Je suppose que je n'ai pas compris la signification de la différence entre regex_match et regex_search jusqu'à ce que vous l'ayez indiqué. Merci encore. Je me demande s'il y a de toute façon à réduire mon "score de réputation" encore plus loin pour afficher mon noobness :). – ossandcad

+0

J'ai testé votre suggestion 1800 INFORMATION pour remplacer regex_match avec regex_search et maintenant je reçois deux chaînes: "0" et "". Je ne pense pas que le 2ème est "1". Des suggestions sur ce que je pourrais encore manquer? – ossandcad

+0

Il semblerait que vous ne capturiez pas les chaînes correspondantes, essayez de mettre le() autour de l'expression –

Questions connexes