IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Boost C++ Discussion :

BOOST :: REGEX INSERTION


Sujet :

Boost C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 35
    Par défaut BOOST :: REGEX INSERTION
    Bonjour à tous,

    J'ai cherché dans la doc de boost::regex comment faire pour insérer une string après chaque match sur une autre string et j'y suis presque arrivé mais la je sèche.. D'ailleurs je me demande bien pourquoi je ne trouve pas de fonction qui le fasse déjà..

    Voici la fonction qui insère le tag "test" dans la string "stringFile" après que chaque match de la regex "expression" soit trouvé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    void insertFlags(std::string& stringFile, const boost::regex& expression)
    {
        std::string::iterator start, end;
        std::string::const_iterator start2, end2;
        std::string test("test;");
     
        start2 = test.begin();
        end2 = test.end();
        start = stringFile.begin();
        end = stringFile.end();
     
        boost::match_results<std::string::iterator> what;
        boost::match_flag_type flags = boost::match_default;
     
        while(regex_search(start, end, what, expression, flags))
        {
            stringFile.insert(what[0].second,start2,end2);
            start = what[0].second;
            end = stringFile.end();
        }
    }
    Mais le problème, c'est que je dois avoir un dépassement au niveau des itérateurs parce que au final, soit le programme m'insère deux fois le tag, soit il plante, soit ca marche !!!
    En fait, les différents cas que je viens d'énumérer apparaissent lorsque le dernier match a été fait et qu'il n'y a plus de résultat..

    J'en peux plus.. HELP !!!

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Ah, le coup classique.
    En fait, quand tu manipules des itérateurs et des strings iIl faut toujours partir du principe qu'un changement de taille de la string invalide tous les itérateurs définis avant.

    resize(), insert(), append(), l'opérateur +=, push_back(), toutes ces fonctions peuvent provoquer des réallocations de mémoire et des copies pour augmenter la taille de la string, et il est impossible de prévoir quand exactement.

    C'est pour ça que tu as des erreurs qui semble aléatoires. Si par chance l'insert ne change pas la taille de la string les itérateurs restent corrects et ça passe, sinon ça crashe

    Il faut faire quelque chose comme ça (j'ai pas testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    while(std::tr1::regex_search(start, end, what, reg, boost::format_first_only))
     // format_first_only s'arrête au premier match trouvé
    {
       // récupère la position juste après le premier match
       int pos = std::distance(stringFile.begin(), what[0].second);
     
       // insère le tag à cette position
       s.insert(pos, test);
     
       // attention après un insert il faut redéfinir start et end
       start = stringFile.begin() + pos + test.size();
       end = stringFile.end();
    }

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 35
    Par défaut ah la je dis Merci !!!
    Je savais que developpez.com était une très belle communauté mais à ce point là , je suis comblé.

    Ta solution marche à merveille et je te remercie profondément.

    Voila la solution complète :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <iterator>
    #include <boost/regex.hpp>
     
    using namespace std;
     
    // purpose:
    // takes the contents of a file in the form of a string
    // and insert a string after each match with your regex
     
    void load_file(std::string& s, std::istream& is)
    {
        s.erase();
        s.reserve(is.rdbuf()->in_avail());
        char c;
        while(is.get(c))
        {
            if(s.capacity() == s.size())
                s.reserve(s.capacity() * 3);
            s.append(1, c);
        }
    }
     
    void insertFlags(std::string& stringFile, const boost::regex& expression)
    {
        std::string::iterator start, end;
        std::string test("insertTest;");
     
        start = stringFile.begin();
        end = stringFile.end();
     
        boost::match_results<std::string::iterator> what;
     
        while(regex_search(start, end, what, expression, boost::format_first_only))
        {
            int pos = std::distance(stringFile.begin(), what[0].second);
            // insère le tag à cette position
            stringFile.insert(pos, test);
            // attention après un insert il faut redéfinir start et end
            start = stringFile.begin() + pos + test.size();
            end = stringFile.end();
        }
    }
     
    int main(int argc, const char** argv){
     
    //    the first regex matchs all C/C++ if bloc
    //    the second regex matchs all else bloc
        boost::regex expression(
        "\\<if\\s*\\([\\s\\w=<>/!%&,:~\\-\\'\\\"\\`\\^\\.\\[\\]\\$\\(\\)\\*\\+\\|\\\\]+\\)\\s*\\{|"
        "\\<else\\s*\\{"
        );
     
        std::cout << "Processing file " << argv[1] << std::endl;
        std::ifstream fs(argv[1]);
        std::string stringFile;
        load_file(stringFile, fs);
        std::string out_name(std::string(argv[1]) + std::string(".c"));
        std::ofstream outputFile(out_name.c_str());
     
        insertFlags(stringFile,expression);
        outputFile << stringFile;
        outputFile.close();
     
        return 0;
    }
    Cet exemple provient de la doc de boost::regex::search et replace sur le site officiel, ainsi que mon travail et l'aide d'Arzar.

    Mais une dernière question me taraude, pourquoi john Maddock n'a-t-il pas implémenté la fonction insert ?

    ha oui, ça compile sous windows XP pro avec cygwin et son package boost_regex-gcc-mt-1_33_1

    J'espère que cela vous aidera.

    A+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. BOOST :: REGEX et UNICODE
    Par Jah77 dans le forum Boost
    Réponses: 3
    Dernier message: 28/01/2009, 22h17
  2. BOOST :: REGEX PATTERN IMPOSSIBLE ?
    Par Jah77 dans le forum Boost
    Réponses: 2
    Dernier message: 26/01/2009, 14h50
  3. [boost] Regex search : trouver l'index
    Par Choupi dans le forum Boost
    Réponses: 4
    Dernier message: 03/12/2007, 11h17
  4. Configurer boost / regex.
    Par OrthoMaker dans le forum Boost
    Réponses: 11
    Dernier message: 06/08/2007, 09h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo