2012-01-13 3 views
0

J'ai quelques questions à propos de boost :: regex: J'ai essayé un exemple ci-dessous.Regex ne renvoie aucun résultat

1) Quel est le 4ème paramètre de sregex_token_iterator? Cela ressemblait à un "match par défaut", mais pourquoi voudriez-vous cela plutôt que de ne rien rendre? Je l'ai essayé sans le 4ème param mais il ne compile pas.

2) Je reçois la sortie: (1, 0) (0, 0) (3, 0) (0, 0) (5, 0)

Quelqu'un peut-il expliquer ce ça va mal?

#include <iostream> 
#include <sstream> 
#include <vector> 
#include <boost/regex.hpp> 

// This example extracts X and Y from (X , Y), (X,Y), (X, Y), etc. 


struct Point 
{ 
    int X; 
    int Y; 
    Point(int x, int y): X(x), Y(y){} 
}; 

typedef std::vector<Point> Polygon; 

int main() 
{ 
    Polygon poly; 
    std::string s = "Polygon: (1.1,2.2), (3, 4), (5,6)"; 

    std::string floatRegEx = "[0-9]*\\.?[0-9]*"; // zero or more numerical characters as you want, then an optional '.', then zero or more numerical characters. 
    // The \\. is for \. because the first \ is the c++ escpape character and the second \ is the regex escape character 
    //const boost::regex r("(\\d+),(\\d+)"); 
    const boost::regex r("(\\s*" + floatRegEx + "\\s*,\\s*" + floatRegEx + "\\s*)"); 
    // \s is white space. We want this to allow (2,3) as well as (2, 3) or (2 , 3) etc. 

    const boost::sregex_token_iterator end; 
    std::vector<int> v; // This type has nothing to do with the type of objects you will be extracting 
    v.push_back(1); 
    v.push_back(2); 

    for (boost::sregex_token_iterator i(s.begin(), s.end(), r, v); i != end;) 
    { 
    std::stringstream ssX; 
    ssX << (*i).str(); 
    float x; 
    ssX >> x; 
    ++i; 

    std::stringstream ssY; 
    ssY << (*i).str(); 
    float y; 
    ssY >> y; 
    ++i; 

    poly.push_back(Point(x, y)); 
    } 

    for(size_t i = 0; i < poly.size(); ++i) 
    { 
    std::cout << "(" << poly[i].X << ", " << poly[i].Y << ")" << std::endl; 
    } 
    std::cout << std::endl; 

    return 0; 
} 
+0

Avez-vous essayé libpcre? –

+0

Je ne voudrais pas introduire plus de dépendances. –

Répondre

0

Votre regex est entièrement facultative:

"[0-9]*\\.?[0-9]*" 

correspond également à la chaîne vide. Donc "(\\s*" + floatRegEx + "\\s*,\\s*" + floatRegEx + "\\s*)" correspond également à une seule virgule.

Vous devriez faire au moins quelque chose obligatoire:

"(?:[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+)" 

Cela permet 1, 1.1, 1. ou .1 mais pas .:

(?:   # Either match... 
[0-9]+  # one or more digits, then 
(?:   # try to match... 
    \.   # a dot 
    [0-9]*  # and optional digits 
)?   # optionally. 
|   # Or match... 
\.[0-9]+ # a dot and one or more digits. 
)   # End of alternation 
+0

Tim, je pensais ça? était juste en train de rendre le point optionnel? Je voulais autoriser 1. ainsi que .1, c'est pourquoi j'ai utilisé [0-9] * des deux côtés de la décimale. Comment puis-je faire juste le. optionnel? En outre, j'ai mis à jour la question avec une analyse plus appropriée. Cependant, je reçois 5 sorties au lieu des 3 que je m'attendrais? –

+0

OK, j'ai modifié mon regex. Va ajouter une explication sous peu. Les '*' s ont rendu les chiffres optionnels aussi. –

+0

Merci Tim. C'est certainement mieux que d'avoir le tout facultatif. Cependant, avec l'entrée codée en dur, mon expression non robuste devrait toujours fonctionner correctement? Je suppose que je fais quelque chose de mal avec le C++ maintenant à cause de la sortie que je montre dans # 2 dans le message original? –

Questions connexes