2012-05-03 2 views
10

Poiché non ho trovato nulla su questo nello documentation, ho pensato di chiederlo qui. Ho il seguente programma (C++ 11):boost :: split lascia i token vuoti all'inizio e alla fine della stringa - è questo comportamento desiderato?

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

using namespace std; 
using namespace boost; 

int main() { 
    string tmp = " #tag #tag1#tag2 #tag3 ####tag4 "; 
    list<iterator_range<string::iterator> > matches; 
    split(matches, tmp, is_any_of("\t #"), token_compress_on); 

    for(auto match: matches) { 
      cout << "'" << match << "'\n"; 
    } 
} 

Il risultato è:

'' 
'tag' 
'tag1' 
'tag2' 
'tag3' 
'tag4' 
'' 

avrei pensato che l'opzione token_compress_on rimuove tutti i gettoni vuote. La soluzione è, ad esempio, per utilizzare boost::trim_if. Tuttavia mi stavo chiedendo se questo è il comportamento desiderato di boost :: split, e perché questo sta accadendo?

(g ++ 4.6.3, incrementare 1.48)

risposta

8

Il comportamento è intenzionale, perché si potrebbe ricreare la stringa (completo di partenza e spazi finali) dalla versione scissione. Boost non sa se quello spazio bianco è significativo o meno per te (potrebbe esserlo, dato che alcuni formati di file, ad esempio, potrebbero forzare spazi iniziali/conteggi di spazio specifici).

È necessario trim_if o trim come se fosse necessario rimuovere gli spazi iniziali/finali.

+0

Forse non ottengo il punto, ma come posso ricreare "#tag # tag1 # tag2 # tag3 #### Tag4" dai gettoni " "," tag "," tag1 "," tag2 "," tag3 "," tag4 "," "? – fdlm

+0

@fdlm Sarebbe specifico per il formato della stringa. Il comportamento di 'boost :: split' è piuttosto generico, ma per alcuni utenti potrebbero essere interessati a preservare i caratteri finali/iniziali che verrebbero altrimenti rimossi dividendoli. Fondamentalmente se ti servono quei personaggi, devi essere esplicito e comporre insieme le funzioni che fanno ciò che ti aspetti. – birryree

+0

Ok, ho capito. Grazie per averlo indicato. – fdlm

7

Se l'argomento eCompress è impostato su token_compress_on, i separatori adiacenti vengono uniti insieme. Altrimenti, ogni due separatori delimitano un token.

Here

Esso non rimuove i gettoni solo li unisce.

0

boost::split restituisce sempre n + 1 token dove n è il numero di separatori nella stringa di input. Quindi non essere sorpreso quando restituisce 1 token quando lo passi una stringa vuota.

La logica dietro di esso è abbastanza semplice. Immagina di analizzare un file CSV. È necessario ottenere esattamente lo stesso numero di elementi indipendentemente dal fatto che l'ultimo token sia vuoto o meno.

È molto più facile rimuovere i token vuoti che indovinare se si suppone che siano o meno nel risultato. Credit

Questo comportamento è simile a Python

>>> len("".split(',')) 
1