Pregunta

Estoy jugando con la biblioteca de cadenas de impulso y acabo de venir a través de la simplicidad impresionante del método de división.

  string delimiters = ",";
  string str = "string, with, comma, delimited, tokens, \"and delimiters, inside a quote\"";
  // If we didn't care about delimiter characters within a quoted section we could us
  vector<string> tokens;  
  boost::split(tokens, str, boost::is_any_of(delimiters));
  // gives the wrong result: tokens = {"string", " with", " comma", " delimited", " tokens", "\"and delimiters", " inside a quote\""}

Lo que sería agradable y concisa ... sin embargo, no parecen funcionar con citas y en su lugar tengo que hacer algo como lo siguiente

string delimiters = ",";
string str = "string, with, comma, delimited, tokens, \"and delimiters, inside a quote\"";
vector<string> tokens; 
escaped_list_separator<char> separator("\\",delimiters, "\"");
typedef tokenizer<escaped_list_separator<char> > Tokeniser;
Tokeniser t(str, separator);
for (Tokeniser::iterator it = t.begin(); it != t.end(); ++it)
    tokens.push_back(*it);
// gives the correct result: tokens = {"string", " with", " comma", " delimited", " tokens", "\"and delimiters, inside a quote\""}

Mi pregunta se puede dividir u otro algoritmo estándar se utiliza cuando se ha citado delimitadores? Gracias a purpledog pero ya tengo una manera no obsoleto de lograr el resultado deseado, simplemente creo que es bastante engorroso y menos que pudiera reemplazarla con una solución más simple más elegante que no lo usaría en general sin antes envolviéndolo en todavía otro método.

EDIT: código actualizado para mostrar resultados y aclarar la pregunta.

¿Fue útil?

Solución

No parece que haya ninguna forma sencilla de hacer esto utilizando el método de impulso :: dividida. La pieza más corta del código que puedo encontrar para hacer esto es

vector<string> tokens; 
tokenizer<escaped_list_separator<char> > t(str, escaped_list_separator<char>("\\", ",", "\""));
BOOST_FOREACH(string s, escTokeniser)
    tokens.push_back(s);  

que sólo es marginalmente más detallado que el fragmento original de

vector<string> tokens;  
boost::split(tokens, str, boost::is_any_of(","));

Otros consejos

Esto va a lograr el mismo resultado que la respuesta de Jamie Cook y sin el bucle explícita.

tokenizer<escaped_list_separator<char> >tok(str);
vector<string> tokens( tok.begin(), tok.end() );

segundo parámetro por defecto de constructores tokenizer a escaped_list_separator<char>("\\", ",", "\"") así que no es necesario. A menos que tenga requisitos diferentes para comas o comillas.

No sé acerca de la biblioteca de impulso :: string pero utilizando el impulso regex_token_iterator podrás expresar delimitadores en términos de expresión regular. Así que sí, puede utilizar delimitadores citados, y cosas mucho más complejas, así.

Tenga en cuenta que esto se hacía con regex_split que ahora está en desuso.

Este es un ejemplo tomado de la doc impulso:

#include <iostream>
#include <boost/regex.hpp>

using namespace std;

int main(int argc)
{
   string s;
   do{
      if(argc == 1)
      {
         cout << "Enter text to split (or \"quit\" to exit): ";
         getline(cin, s);
         if(s == "quit") break;
      }
      else
         s = "This is a string of tokens";

      boost::regex re("\\s+");
      boost::sregex_token_iterator i(s.begin(), s.end(), re, -1);
      boost::sregex_token_iterator j;

      unsigned count = 0;
      while(i != j)
      {
         cout << *i++ << endl;
         count++;
      }
      cout << "There were " << count << " tokens found." << endl;

   }while(argc == 1);
   return 0;
}

Si el programa se inicia con Hello World como argumento la salida es:

hello
world
There were 2 tokens found.

Cambiar impulso :: expresiones regulares re ( "\ s +"); en impulso :: expresiones regulares Re ( "\", \ ""); dividiría delimitadores citados . comenzando el programa con hola "" mundo como argumento también se traduciría en:

hello
world
There were 2 tokens found.

Pero sospecho que quiere tratar con cosas como que: "hola", "mundo" , en cuyo caso, una solución es:

  1. split con coma solamente
  2. a continuación, eliminar el "" (posiblemente usando realce / algoritmo / cadena / trim.hpp o la biblioteca de expresiones regulares).

EDIT: añadido salida del programa

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top