2009-08-09 6 views
11

Je cherchais boost :: tokenizer, et j'ai trouvé que la documentation est très fine. Est-il possible de faire une chaîne comme "dauphin - singe - babouin" et de faire de chaque mot un jeton, ainsi que chaque double tiret un jeton? À partir des exemples, je n'ai vu que les délimiteurs à caractère unique autorisés. La bibliothèque n'est-elle pas assez avancée pour les délimiteurs plus compliqués?Utiliser boost :: tokenizer avec des délimiteurs de chaînes

+1

Juste curieux de savoir pourquoi cela est marqué wiki communautaire? –

+0

Je pensais que cela permettrait aux autres de clarifier ma question au cas où il serait un peu diffus. Peut-être devrais-je lire ce que c'est, jusqu'à la prochaine fois. – Martin

Répondre

0

Il semble que vous aurez besoin d'écrire le vôtre TokenizerFunction pour faire ce que vous voulez.

+0

Je vois. J'espérais qu'il y aurait quelque chose de pré-fabriqué, mais j'imagine que j'espérais trop. – Martin

1

Une option consiste à essayer boost :: regex. Pas sûr de la performance par rapport à un tokenizer personnalisé.

std::string s = "dolphin--monkey--baboon"; 

boost::regex re("[a-z|A-Z]+|--"); 
boost::sregex_token_iterator iter(s.begin(), s.end() , re, 0); 
boost::sregex_token_iterator end_iter; 

while(iter != end_iter) 
{ 
    std::cout << *iter << '\n'; 
    ++iter; 
} 
+0

C'est gentil. Si cela fonctionne, il obtient mon vote. :) –

10

L'utilisation de iter_split vous permet d'utiliser plusieurs jetons de caractères. Le code ci-dessous produirait ce qui suit:

dauphin
mon-clé
babouin

#include <iostream> 
#include <boost/foreach.hpp> 
#include <boost/algorithm/string.hpp> 
#include <boost/algorithm/string/iter_find.hpp> 

    // code starts here 
    std::string s = "dolphin--mon-key--baboon"; 
    std::list<std::string> stringList; 
    boost::iter_split(stringList, s, boost::first_finder("--")); 

    BOOST_FOREACH(std::string token, stringList) 
    {  
     std::cout << token << '\n'; ; 
    } 
+1

Cela a l'inconvénient de créer une copie de la chaîne entière. Si la chaîne tokenized est grande, c'est un problème. Le tokenizer boost ne fait pas ça. –

2

Je sais que le thème est assez vieux, mais il est indiqué dans les liens dans Google quand je la recherche « boost tokenizer par chaîne »

donc je vais ajouter ma variante de TokenizerFunction, juste au cas où:

class FindStrTFunc 
{ 
public: 
    FindStrTFunc() : m_str(g_dataSeparator) 
    { 
    } 

    bool operator()(std::string::const_iterator& next, 
     const std::string::const_iterator& end, std::string& tok) const 
    { 
     if (next == end) 
     { 
      return false; 
     } 
     const std::string::const_iterator foundToken = 
      std::search(next, end, m_str.begin(), m_str.end()); 
     tok.assign(next, foundToken); 
     next = (foundToken == end) ? end : foundToken + m_str.size(); 
     return true; 
    } 

    void reset() 
    { 
    } 

private: 
    std::string m_str; 
}; 

après que nous pouvons créer

boost::tokenizer<FindStrTFunc> tok("some input...some other input"); 

et utiliser, comme d'habitude un coup de pouce tokenizer

+0

la mise en œuvre n'est pas idéale (pourrait avoir des bugs), c'est juste un exemple – Alek86

Questions connexes