Ich analysiere eine Zeichenfolge in C++ mit dem folgenden:
string parsed,input="text to be parsed";
stringstream input_stringstream(input);
if(getline(input_stringstream,parsed,' '))
{
// do some processing.
}
Das Parsen mit einem einzelnen Zeichen als Begrenzer ist in Ordnung. Was aber, wenn ich eine Zeichenkette als Begrenzer verwenden möchte?
Beispiel: Ich möchte aufteilen:
scott>=tiger
mit >= als Trennzeichen, damit ich scott und tiger erhalte.
Sie können die Funktion std::string::find()
verwenden, um die Position des Begrenzungszeichens zu finden, und dann std::string::substr()
verwenden, um ein Token zu erhalten.
Beispiel:
std::string s = "scott>=tiger";
std::string delimiter = ">=";
std::string token = s.substr(0, s.find(delimiter)); // token is "scott"
Die Funktion find(const string& str, size_t pos = 0)
gibt die Position des ersten Vorkommens von str
in der Zeichenkette zurück, oder npos
, wenn die Zeichenkette nicht gefunden wird.
Die Funktion substr(size_t pos = 0, size_t n = npos)
gibt eine Teilzeichenkette des Objekts zurück, beginnend an der Position pos
und der Länge npos
.
Wenn Sie mehrere Begrenzungszeichen haben, können Sie, nachdem Sie ein Token extrahiert haben, dieses entfernen (einschließlich Begrenzungszeichen), um mit nachfolgenden Extraktionen fortzufahren (wenn Sie die ursprüngliche Zeichenkette beibehalten wollen, verwenden Sie einfach s = s.substr(pos + delimiter.length());
):
s.erase(0, s.find(delimiter) + delimiter.length());
Auf diese Weise können Sie leicht eine Schleife bilden, um jedes Token zu erhalten.
std::string s = "scott>=tiger>=mushroom";
std::string delimiter = ">=";
size_t pos = 0;
std::string token;
while ((pos = s.find(delimiter)) != std::string::npos) {
token = s.substr(0, pos);
std::cout << token << std::endl;
s.erase(0, pos + delimiter.length());
}
std::cout << s << std::endl;
Ausgabe:
scott
tiger
mushroom
Mit strtok können Sie mehrere Zeichen als Begrenzungszeichen übergeben. Ich wette, wenn Sie ">=" übergeben würden, würde Ihre Beispielzeichenkette korrekt aufgespalten werden (obwohl > und = als einzelne Begrenzungszeichen gezählt werden).
EDIT: Wenn Sie nicht c_str()
zur Konvertierung von string in char* verwenden wollen, können Sie substr und find_first_of zur Tokenisierung verwenden.
string token, mystring("scott>=tiger");
while(token != mystring){
token = mystring.substr(0,mystring.find_first_of(">="));
mystring = mystring.substr(mystring.find_first_of(">=") + 1);
printf("%s ",token.c_str());
}
Ich würde boost::tokenizer
verwenden. Hier's Dokumentation, die erklärt, wie man eine geeignete Tokenizer-Funktion erstellt: http://www.boost.org/doc/libs/1_52_0/libs/tokenizer/tokenizerfunction.htm
Hier's eine, die für Ihren Fall funktioniert.
struct my_tokenizer_func
{
template<typename It>
bool operator()(It& next, It end, std::string & tok)
{
if (next == end)
return false;
char const * del = ">=";
auto pos = std::search(next, end, del, del + 2);
tok.assign(next, pos);
next = pos;
if (next != end)
std::advance(next, 2);
return true;
}
void reset() {}
};
int main()
{
std::string to_be_parsed = "1) one>=2) two>=3) three>=4) four";
for (auto i : boost::tokenizer<my_tokenizer_func>(to_be_parsed))
std::cout << i << '\n';
}