C++ tokenize


Esempio

Elencato dal meno costoso al più costoso in fase di esecuzione:

  1. str::strtok è il metodo di tokenizzazione standard più economico fornito, consente inoltre di modificare il delimitatore tra i token, ma comporta 3 difficoltà con il C ++ moderno:

    • std::strtok non può essere utilizzato su più strings contemporaneamente (anche se alcune implementazioni si estendono per supportare questo, come ad esempio: strtok_s )
    • Per lo stesso motivo, std::strtok non può essere utilizzato su più thread simultaneamente (questo potrebbe essere tuttavia definito dall'implementazione, ad esempio: l'implementazione di Visual Studio è thread-safe )
    • Chiamare std::strtok modifica la std::string cui sta operando, quindi non può essere usata su const string s, const char* s o stringhe letterali, per tokenizzare uno di questi con std::strtok o per operare su un std::string chi ha il contenuto da conservare, l'input dovrebbe essere copiato, quindi la copia può essere utilizzata

    Generalmente, qualsiasi costo di queste opzioni sarà nascosto nel costo di allocazione dei token, ma se è richiesto l'algoritmo più economico e le difficoltà di std::strtok non sono sovrastimabili, si consideri una soluzione filata a mano .

// String to tokenize
std::string str{ "The quick brown fox" };
// Vector to store tokens
vector<std::string> tokens;

for (auto i = strtok(&str[0], " "); i != NULL; i = strtok(NULL, " "))
    tokens.push_back(i);

Esempio dal vivo

  1. std::istream_iterator utilizza iterativamente l'operatore di estrazione del flusso. Se l'input std::string è delimitato da spazi bianchi, questo è in grado di espandersi sull'opzione std::strtok eliminando le sue difficoltà, consentendo la tokenizzazione in linea supportando in tal modo la generazione di un const vector<string> e aggiungendo il supporto per più delimitare il carattere dello spazio bianco:
// String to tokenize
const std::string str("The  quick \tbrown \nfox");
std::istringstream is(str);
// Vector to store tokens
const std::vector<std::string> tokens = std::vector<std::string>(
                                        std::istream_iterator<std::string>(is),
                                        std::istream_iterator<std::string>());

Esempio dal vivo

  1. std::regex_token_iterator usa una std::regex to iterativamente tokenize. Fornisce una definizione delimitatore più flessibile. Ad esempio, virgole non delimitate e spazi bianchi:
C ++ 11
// String to tokenize
const std::string str{ "The ,qu\\,ick ,\tbrown, fox" };
const std::regex re{ "\\s*((?:[^\\\\,]|\\\\.)*?)\\s*(?:,|$)" };
// Vector to store tokens
const std::vector<std::string> tokens{ 
    std::sregex_token_iterator(str.begin(), str.end(), re, 1), 
    std::sregex_token_iterator() 
};

Esempio dal vivo

Vedi l' esempio regex_token_iterator per maggiori dettagli.