Teilen Sie eine Zeichenfolge durch mehrere Trennzeichen in Wörter auf

Lesezeit: 6 Minuten

Teilen Sie eine Zeichenfolge durch mehrere Trennzeichen in Worter auf
Sergej G

Ich habe Text (sinnvoller Text oder arithmetischer Ausdruck) und möchte ihn in Wörter aufteilen.
Wenn ich ein einzelnes Trennzeichen hätte, würde ich verwenden:

std::stringstream stringStream(inputString);
std::string word;
while(std::getline(stringStream, word, delimiter)) 
{
    wordVector.push_back(word);
}

Wie kann ich die Zeichenfolge mit mehreren Trennzeichen in Token aufteilen?

  • Boost.StringAlgorithm oder Boost.Tokenizer würden helfen.

    – K-ballo

    1. Oktober 2011 um 17:14 Uhr

  • Oder eine Idee, die Sie dieser Antwort entnehmen können: stackoverflow.com/questions/4888879/…

    – Nawaz

    1. Oktober 2011 um 17:17 Uhr

  • @K-ballo: Laut der Frage sollten Sie keine externen Bibliotheken wie Boost verwenden.

    – masud

    1. Oktober 2011 um 17:17 Uhr


  • @MasoudM.: Zählt Boost immer noch als externe Bibliothek 😉 ? Soweit es mich betrifft, ist Boost wie meine Standardbibliothek, es ist eingebaut!

    – Matthias M.

    1. Oktober 2011 um 17:30 Uhr

  • @MatthieuM.: Dann ist Qt auch für mich keine externe Bibliothek.

    – masud

    1. Oktober 2011 um 17:51 Uhr

Angenommen, eines der Trennzeichen ist ein Zeilenumbruch, wird im Folgenden die Zeile gelesen und durch die Trennzeichen weiter geteilt. Für dieses Beispiel habe ich die Trennzeichen Leerzeichen, Apostroph und Semikolon gewählt.

std::stringstream stringStream(inputString);
std::string line;
while(std::getline(stringStream, line)) 
{
    std::size_t prev = 0, pos;
    while ((pos = line.find_first_of(" ';", prev)) != std::string::npos)
    {
        if (pos > prev)
            wordVector.push_back(line.substr(prev, pos-prev));
        prev = pos+1;
    }
    if (prev < line.length())
        wordVector.push_back(line.substr(prev, std::string::npos));
}

  • Sie sind zu schnell für mich: p Wenn Newline kein Trennzeichen ist, dann funktioniert es einfach, eines der “normalen” Trennzeichen auszuwählen (und es aus der inneren Schleife zu entfernen).

    – Matthias M.

    1. Oktober 2011 um 17:32 Uhr

Wenn Sie Boost haben, könnten Sie Folgendes verwenden:

#include <boost/algorithm/string.hpp>
std::string inputString("One!Two,Three:Four");
std::string delimiters("|,:");
std::vector<std::string> parts;
boost::split(parts, inputString, boost::is_any_of(delimiters));

  • das ist, als würde man jemanden bitten, ein Glas Gurken zu öffnen, und man zieht eine Kettensäge heraus.

    – Dmitri

    27. Juli 2019 um 3:29 Uhr


1646350809 900 Teilen Sie eine Zeichenfolge durch mehrere Trennzeichen in Worter auf
darune

Verwenden std::regex

EIN std::regex kann Strings in wenigen Zeilen aufteilen:

std::regex re("[\\|,:]");
std::sregex_token_iterator first{input.begin(), input.end(), re, -1}, last;//the '-1' is what makes the regex split (-1 := what was not matched)
std::vector<std::string> tokens{first, last};

Versuch es selber

  • Wie kommt es, dass dies nur wenige positive Stimmen hat? Das ist absolut genial! Wenige Zeilen, keine Notwendigkeit für eine externe Bibliothek und etwas Neues. Danke sehr !

    – Berkay Berabi

    8. Juli 2020 um 9:31 Uhr

  • @berkayberabi kein Problem – es war eine späte Antwort, ich denke, das ist der Grund. Wenn Sie möchten, können Sie eine Prämie ausschreiben, um eine vorhandene Antwort zu belohnen (die auch Aufmerksamkeit erregt).

    – darune

    8. Juli 2020 um 9:40 Uhr


  • Hallo, ich habe nicht so viel Ruf. Aber eine Frage habe ich noch. Wenn ich auch basierend auf Klammern als Trennzeichen teilen möchte ([]) wie kann ich die Klammern übergeben. Wenn ich sie einfach eingebe, werden sie als ein weiterer regulärer Ausdruck interpretiert und es funktioniert nicht

    – Berkay Berabi

    9. Juli 2020 um 9:36 Uhr

  • @berkayberabi Flucht über \\]

    – darune

    9. Juli 2020 um 11:08 Uhr


  • Wie wäre es mit diesem Fall? text = “Windows. Apple”; Ich will nur sehen [‘Windows’ , ‘Apple’]. Diese Regex gibt [Windows ,’ ‘, Apple]die ein Leerzeichen (‘ ‘) enthält, möchte ich nicht.

    – cpchung

    8. Mai 2021 um 3:06 Uhr

Ich weiß nicht, warum niemand auf den manuellen Weg hingewiesen hat, aber hier ist er:

const std::string delims(";,:. \n\t");
inline bool isDelim(char c) {
    for (int i = 0; i < delims.size(); ++i)
        if (delims[i] == c)
            return true;
    return false;
}

und in Funktion:

std::stringstream stringStream(inputString);
std::string word; char c;

while (stringStream) {
    word.clear();

    // Read word
    while (!isDelim((c = stringStream.get()))) 
        word.push_back(c);
    if (c != EOF)
        stringStream.unget();

    wordVector.push_back(word);

    // Read delims
    while (isDelim((c = stringStream.get())));
    if (c != EOF)
        stringStream.unget();
}

Auf diese Weise können Sie etwas Nützliches mit den Delims anstellen, wenn Sie möchten.

Wenn Sie daran interessiert sind, wie Sie es selbst machen und keinen Boost verwenden.

Angenommen, die Trennzeichenfolge kann sehr lang sein – sagen wir M, und jedes Zeichen in Ihrer Zeichenfolge zu prüfen, ob es sich um ein Trennzeichen handelt, würde jeweils O (M) kosten, also in einer Schleife für alle Zeichen in Ihrer ursprünglichen Zeichenfolge, sagen wir mal in der Länge N, ist O(M*N).

Ich würde ein Wörterbuch verwenden (wie eine Karte – “Trennzeichen” zu “Booleans” – aber hier würde ich ein einfaches boolesches Array verwenden, das für jedes Trennzeichen true im Index = ASCII-Wert hat).

Iterieren Sie nun über die Zeichenfolge und prüfen Sie, ob das Zeichen ein Trennzeichen ist, O (1), was uns schließlich O (N) insgesamt ergibt.

Hier ist mein Beispielcode:

const int dictSize = 256;    

vector<string> tokenizeMyString(const string &s, const string &del)
{
    static bool dict[dictSize] = { false};

    vector<string> res;
    for (int i = 0; i < del.size(); ++i) {      
        dict[del[i]] = true;
    }

    string token("");
    for (auto &i : s) {
        if (dict[i]) {
            if (!token.empty()) {
                res.push_back(token);
                token.clear();
            }           
        }
        else {
            token += i;
        }
    }
    if (!token.empty()) {
        res.push_back(token);
    }
    return res;
}


int main()
{
    string delString = "MyDog:Odie, MyCat:Garfield  MyNumber:1001001";
//the delimiters are " " (space) and "," (comma) 
    vector<string> res = tokenizeMyString(delString, " ,");

    for (auto &i : res) {

        cout << "token: " << i << endl;
    }
return 0;
}

Hinweis: tokenizeMyString gibt den Vektor nach Wert zurück und erstellt ihn zuerst auf dem Stack, also nutzen wir hier die Leistung des Compilers >>> RVO – Rückgabewertoptimierung 🙂

1646350810 842 Teilen Sie eine Zeichenfolge durch mehrere Trennzeichen in Worter auf
BernhardWebstudio

Und hier, Ewigkeiten später, eine Lösung mit C++20:

constexpr std::string_view words{"Hello-_-C++-_-20-_-!"};
constexpr std::string_view delimeters{"-_-"};
for (const std::string_view word : std::views::split(words, delimeters)) {
    std::cout << std::quoted(word) << ' ';
}
// outputs: Hello C++ 20!

Erforderliche Header:

#include <ranges>
#include <string_view>

Referenz: https://en.cppreference.com/w/cpp/ranges/split_view

1646350810 907 Teilen Sie eine Zeichenfolge durch mehrere Trennzeichen in Worter auf
Porsche9II

Verwenden der range-v3-Bibliothek von Eric Niebler:

https://godbolt.org/z/ZnxfSa

#include <string>
#include <iostream>
#include "range/v3/all.hpp"

int main()
{
    std::string s = "user1:192.168.0.1|user2:192.168.0.2|user3:192.168.0.3";
    auto words = s  
        | ranges::view::split('|')
        | ranges::view::transform([](auto w){
            return w | ranges::view::split(':');
        });
      ranges::for_each(words, [](auto i){ std::cout << i  << "\n"; });
}

  • Wie funktioniert das bei mehreren Trennzeichen?

    – Daniel Schlößer

    26. Mai 2021 um 13:33 Uhr

  • Du meinst sowas wie godbolt.org/z/1sYzhe7zq ?

    – Porsche9II

    16. Juni 2021 um 18:57 Uhr

928660cookie-checkTeilen Sie eine Zeichenfolge durch mehrere Trennzeichen in Wörter auf

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy