C++ Tokenizar


Ejemplo

Listado de menos costoso a más costoso en tiempo de ejecución:

  1. str::strtok es el método de tokenización estándar más barato, también permite que el delimitador se modifique entre tokens, pero incurre en 3 dificultades con C ++ moderno:

    • std::strtok no se puede usar en varias strings al mismo tiempo (aunque algunas implementaciones se extienden para admitir esto, como: strtok_s )
    • Por la misma razón, std::strtok no se puede usar en varios subprocesos simultáneamente (sin embargo, esto puede ser definido por la implementación, por ejemplo: la implementación de Visual Studio es segura para subprocesos )
    • Al llamar a std::strtok modifica la std::string que está funcionando, por lo que no se puede usar en const string const char* , caracteres const char* o cadenas literales, para señalizar cualquiera de ellas con std::strtok o para operar en una std::string cuyo contenido debe conservarse, la entrada debería copiarse, luego la copia podría operarse

    En general, cualquiera de estas opciones de costo estará oculto en el costo de asignación de los tokens, pero si se requiere el algoritmo más barato y las dificultades de std::strtok strtok no se pueden superar, considere una solución manual .

// 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);

Ejemplo vivo

  1. std::istream_iterator usa el operador de extracción del flujo de forma iterativa. Si la entrada std::string está delimitada por espacios en blanco, esto es capaz de expandirse en la opción std::strtok eliminando sus dificultades, permitiendo la tokenización en línea, lo que permite la generación de un const vector<string> , y agregando soporte para múltiples delimitando caracteres de espacio en blanco:
// 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>());

Ejemplo vivo

  1. El std::regex_token_iterator utiliza un std::regex para tokenizar iterativamente. Proporciona una definición de delimitador más flexible. Por ejemplo, comas no delimitadas y espacios en blanco:
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() 
};

Ejemplo vivo

Vea el ejemplo regex_token_iterator para más detalles.