2009-08-09 6 views
11

Szukałem boost :: tokenizer i stwierdziłem, że dokumentacja jest bardzo cienka. Czy da się tokenizować ciąg znaków, taki jak "delfin - małpa - pawian" i czy każde słowo jest żetonem, a także podwójnym żetonem? Z przykładów widziałem tylko separatory pojedynczych znaków. Czy biblioteka nie jest wystarczająco zaawansowana dla bardziej skomplikowanych ograniczników?Używanie boost :: tokenizer z ogranicznikami ciągów znaków

+1

prostu ciekawi, dlaczego tak jest oznaczony Wiki? –

+0

Pomyślałem, że pozwoliłoby to innym wyjaśnić moje pytanie na wypadek, gdyby było trochę rozproszone. Być może powinienem przeczytać, co to jest, do następnego razu. – Martin

Odpowiedz

0

Wygląda na to, że musisz napisać własny kod TokenizerFunction, aby zrobić to, co chcesz.

+0

Rozumiem. Miałem nadzieję, że coś będzie gotowe, ale myślę, że liczyłem na zbyt wiele. – Martin

1

Jedną z opcji jest próba zwiększenia :: regex. Nie jesteś pewien wydajności w porównaniu do niestandardowego tokenizera.

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

To jest miłe. Jeśli to działa, dostaje mój głos. :) –

10

używanie iter_split pozwala na używanie wielu tokenów znaków. Poniższy kod da następujący:

delfin
mon-key
pawian

#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

Ma to wadę tworzenia kopii całego ciągu znaków. Jeśli token jest duży, jest to problem. Tokenizer doładowania nie robi tego. –

2

Wiem, że temat jest dość stary, ale jest to pokazane w najlepszych linków w google, kiedy szukaj „zwiększyć tokenizer przez ciąg”

więc dodam moje wariant TokenizerFunction, na wszelki wypadek:

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; 
}; 

po możemy stworzyć

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

i używać, jak zwykły impuls Tokenizer

+0

implementacja nie jest idealna (może mieć błędy), to tylko przykład – Alek86