2012-05-03 8 views
10

Da ich nichts dazu in der documentation finden konnte, dachte ich, ich frage es hier. Ich habe das folgende Programm (C++ 11):boost :: split lässt leere Token am Anfang und am Ende der Zeichenfolge - ist dies das gewünschte Verhalten?

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

Die Ausgabe lautet:

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

Ich hätte gedacht, dass die token_compress_on Option alle leeren Token entfernt. Die Lösung ist beispielsweise boost::trim_if zu verwenden. Trotzdem habe ich mich gefragt, ob dies das gewünschte Verhalten von boost :: split ist und warum dies passiert?

(g ++ 4.6.3, steigern 1,48)

Antwort

8

Das Verhalten ist beabsichtigt, da Sie die Zeichenfolge (komplett mit Start- und Leerzeichen) von der geteilten Version neu erstellen können. Boost weiß nicht, ob dieser Whitespace für Sie von Bedeutung ist oder nicht (dies könnte der Fall sein, da einige Dateiformate beispielsweise führende Leerzeichen/spezifische Leerzeichenanzahl erzwingen könnten).

Sie sollten trim_if oder trim wie Sie sind, wenn Sie führende/nachstehende Leerzeichen entfernen müssen.

+0

Vielleicht den Punkt, den ich nicht bekommen Python, aber wie kann ich "#tag # tag1 # tag2 # tag3 #### tag4" von den Token "neu "," tag "," tag1 "," tag2 "," tag3 "," tag4 "," "? – fdlm

+0

@fdlm Das wäre spezifisch für das Format Ihrer Zeichenfolge. Das Verhalten von 'boost :: split' ist ziemlich allgemein, aber für einige Benutzer mag es wichtig sein, nachlaufende/führende Zeichen zu behalten, die ansonsten durch Teilen auf ihnen entfernt würden. Wenn Sie diese Zeichen brauchen, müssen Sie explizit sein und Funktionen zusammenstellen, die das tun, was Sie erwarten. – birryree

+0

Ok, ich habe es. Vielen Dank, dass Sie darauf hingewiesen haben. – fdlm

7

Wenn das Argument eCompress auf token_compress_on gesetzt ist, werden benachbarte Separatoren zusammengeführt. Ansonsten begrenzen alle zwei Trennzeichen ein Token.

Here

Es entfernt nicht die Tokens nur sie übergeht.

0

boost::split gibt immer n + 1 Tokens zurück, wobei n die Anzahl der Trennzeichen in der Eingabezeichenfolge ist. Seien Sie also nicht überrascht, wenn Sie 1 Token zurückgeben, wenn Sie eine leere Zeichenfolge übergeben.

Die Begründung dahinter ist recht einfach. Stellen Sie sich vor, Sie analysieren eine CSV-Datei. Sie müssen genau die gleiche Anzahl an Elementen erhalten, unabhängig davon, ob das letzte Token leer ist oder nicht.

Es ist viel einfacher, die leeren Token zu entfernen, als zu erraten, ob sie im Ergebnis enthalten sein sollen oder nicht. Credit

Dieses Verhalten ist ähnlich

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