C++ Get String zwischen zwei Trennzeichen String

Lesezeit: 6 Minuten

Gibt es eine eingebaute Funktion, die zwei Get-Strings zwischen zwei Trennzeichen-Strings in C/C++ enthält?

Meine Eingabe sieht aus wie

_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_

Und meine Ausgabe sollte sein

_0_192.168.1.18_

Danke im Voraus…

  • @PaulR: Was ist falsch an C++11 ?

    – Mike Housky

    14. September 2013 um 10:40 Uhr

  • Ja, ich habe es mit strtok() versucht, aber wenn etwas fertig ist, kann ich das verwenden …

    – Haris

    14. September 2013 um 10:42 Uhr

  • @Mike: Nun ja, aber nicht jeder verwendet C++11

    – PaulR

    14. September 2013 um 10:43 Uhr

  • Schub? C++ ? was sind das für kommentare Ein einfaches Problem braucht eine einfache Lösung: standardmäßiges abwärtskompatibles ANSI C++ und nichts anderes als die STL

    – Didac Perez Parera

    14. September 2013 um 10:58 Uhr


Benutzer-Avatar
Saksham

Sie können Folgendes tun:

string str = "STARTDELIMITER_0_192.168.1.18_STOPDELIMITER";
unsigned first = str.find(STARTDELIMITER);
unsigned last = str.find(STOPDELIMITER);
string strNew = str.substr (first,last-first);

In Anbetracht Ihrer STOPDELIMITER Trennzeichen wird nur einmal am Ende vorkommen.

BEARBEITEN:

Da das Trennzeichen mehrfach vorkommen kann, ändern Sie Ihre Anweisung zum Auffinden von STOPDELIMITER in:

unsigned last = str.find_last_of(STOPDELIMITER);

Dadurch erhalten Sie Text zwischen dem ersten STARTDELIMITER und dem LAST STOPDELIMITER, obwohl sie mehrmals wiederholt werden.

  • H danke für die Antwort, aber ich bekomme das Ergebnis wie STARTDELIMITER_0_192.168.1.18_

    – Haris

    14. September 2013 um 10:51 Uhr

  • @Haris Ich glaube, du hast am Anfang einen Unterstrich.

    – Saksham

    14. September 2013 um 10:53 Uhr

  • @SakshamJa, das habe ich, und das Trennzeichen kann mehrmals vorkommen

    – Haris

    14. September 2013 um 10:56 Uhr


  • Aber das ist ein Zeichentrennzeichen. Es ist keine Saite zwischen zwei Saiten.

    – hB0

    30. Oktober 2013 um 23:03 Uhr

Benutzer-Avatar
ifma

Ich habe keine Ahnung, wie die oberste Antwort so viele Stimmen erhalten hat, dass sie es getan hat, als die Frage eindeutig fragt, wie man eine Zeichenfolge zwischen zwei Trennzeichen erhält Saitenund kein Zeichenpaar.

Wenn Sie dies tun möchten, müssen Sie die Länge des Zeichenfolgenbegrenzers berücksichtigen, da es sich nicht nur um ein einzelnes Zeichen handelt.

Fall 1: Beide Trennzeichen sind eindeutig:

Gegeben eine Zeichenfolge _STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_ die Sie extrahieren möchten _0_192.168.1.18_ von können Sie die oberste Antwort so ändern, um den gewünschten Effekt zu erzielen. Dies ist die einfachste Lösung, ohne zusätzliche Abhängigkeiten (z. B. Boost) einzuführen:

#include <iostream>
#include <string>
 
std::string get_str_between_two_str(const std::string &s,
        const std::string &start_delim,
        const std::string &stop_delim)
{
    unsigned first_delim_pos = s.find(start_delim);
    unsigned end_pos_of_first_delim = first_delim_pos + start_delim.length();
    unsigned last_delim_pos = s.find(stop_delim);
 
    return s.substr(end_pos_of_first_delim,
            last_delim_pos - end_pos_of_first_delim);
}
 
int main() {
    // Want to extract _0_192.168.1.18_
    std::string s = "_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_";
    std::string s2 = "ABC123_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_XYZ345";
 
    std::string start_delim = "_STARTDELIMITER";
    std::string stop_delim = "STOPDELIMITER_";
 
    std::cout << get_str_between_two_str(s, start_delim, stop_delim) << std::endl;
    std::cout << get_str_between_two_str(s2, start_delim, stop_delim) << std::endl;
 
    return 0;
}

Wird gedruckt _0_192.168.1.18_ zweimal.

Es ist notwendig, die Position des ersten Trennzeichens im zweiten Argument hinzuzufügen std::string::substr wie last - (first + start_delim.length()) um sicherzustellen, dass der gewünschte innere String immer noch korrekt extrahiert wird, falls sich das Starttrennzeichen nicht ganz am Anfang des Strings befindet, wie im zweiten Fall oben gezeigt.

Siehe die Demo.

Fall 2: Eindeutiges erstes Trennzeichen, nicht eindeutiges zweites Trennzeichen:

Angenommen, Sie möchten eine Zeichenfolge zwischen einem eindeutigen Trennzeichen und dem ersten nicht eindeutigen Trennzeichen erhalten, das nach dem ersten Trennzeichen auftritt. Sie könnten die obige Funktion ändern get_str_between_two_str benutzen find_first_of stattdessen, um den gewünschten Effekt zu erzielen:

std::string get_str_between_two_str(const std::string &s,
        const std::string &start_delim,
        const std::string &stop_delim)
{
    unsigned first_delim_pos = s.find(start_delim);
    unsigned end_pos_of_first_delim = first_delim_pos + start_delim.length();
    unsigned last_delim_pos = s.find_first_of(stop_delim, end_pos_of_first_delim);
    
    return s.substr(end_pos_of_first_delim,
            last_delim_pos - end_pos_of_first_delim);
}

Wenn Sie stattdessen Zeichen zwischen dem ersten eindeutigen Trennzeichen und dem letzten gefundenen zweiten Trennzeichen erfassen möchten, wie es der Fragesteller oben kommentiert hat, verwenden Sie find_last_of stattdessen.

Fall 3: Nicht eindeutiges erstes Trennzeichen, eindeutiges zweites Trennzeichen:

Sehr ähnlich zu Fall 2, kehren Sie einfach die Logik zwischen dem ersten und dem zweiten Trennzeichen um.

Fall 4: Beide Trennzeichen sind nicht eindeutig:

Erstellen Sie wieder, sehr ähnlich wie in Fall 2, einen Container, um alle Zeichenfolgen zwischen einem der beiden Trennzeichen zu erfassen. Durchlaufen Sie die Zeichenfolge und aktualisieren Sie die Position des ersten Trennzeichens so, dass sie gleich der Position des zweiten Trennzeichens ist, wenn es angetroffen wird, und fügen Sie die Zeichenfolge dazwischen zum Container hinzu. Wiederhole bis std::string:npos ist erreicht.

Um eine Zeichenfolge zwischen 2 Trennzeichenfolgen ohne Leerzeichen zu erhalten.

string str = "STARTDELIMITER_0_192.168.1.18_STOPDELIMITER";

string startDEL = "STARTDELIMITER";  
// this is really only needed for the first delimiter
string stopDEL =  "STOPDELIMITER";

unsigned firstLim = str.find(startDEL);
unsigned lastLim = str.find(stopDEL);

string strNew = str.substr (firstLim,lastLim); 
//This won't exclude the first delimiter because there is no whitespace

strNew = strNew.substr(firstLim + startDEL.size()) 
// this will start your substring after the delimiter

Ich habe versucht, die beiden Teilzeichenfolgenfunktionen zu kombinieren, aber es hat begonnen, das STOPDELIMITER zu drucken

Ich hoffe, das hilft

Benutzer-Avatar
Jan Korus

Ich hoffe, Sie haben nichts dagegen, dass ich mit einer anderen Frage antworte 🙂 Ich würde boost::split oder boost::split_iter verwenden.
http://www.boost.org/doc/libs/1_54_0/doc/html/string_algo/usage.html#idp166856528

Beispielcode finden Sie in dieser SO-Frage: Wie vermeidet man leere Tokens beim Splitten mit boost::iter_split?

Angenommen, Sie müssen das fünfte Argument (Marke) aus der folgenden Ausgabe erhalten:

zoneid:zonename:state:zonepath:uuid:brand:ip-type:r/w:file-mac-profile

Sie können keine „str.find“-Funktion verwenden, da sie sich in der Mitte befindet, aber Sie können „strtok“ verwenden. z.B

char *brand;
brand = strtok( line, ":" );
for (int i=0;i<4;i++) {
    brand = strtok( NULL, ":" );
}

Benutzer-Avatar
Falke

Dies ist eine späte Antwort, aber dies könnte auch funktionieren:

string strgOrg= "STARTDELIMITER_0_192.168.1.18_STOPDELIMITER";
string strg= strgOrg;

strg.replace(strg.find("STARTDELIMITER"), 14, "");
strg.replace(strg.find("STOPDELIMITER"), 13, "");

Hoffe es funktioniert bei anderen.

Benutzer-Avatar
Telekom

void getBtwString(std::string oStr, std::string sStr1, std::string sStr2, std::string &rStr)
 {  
    int start = oStr.find(sStr1);   
    if (start >= 0)     
    {       
      string tstr = oStr.substr(start + sStr1.length());        
      int stop = tstr.find(sStr2);      
      if (stop >1)          
        rStr = oStr.substr(start + sStr1.length(), stop);
      else
        rStr ="error";  
    }
    else
       rStr = "error"; }

oder wenn Sie Windows verwenden und Zugriff auf c ++ 14 haben, Folgendes:

void getBtwString(std::string oStr, std::string sStr1, std::string sStr2, std::string &rStr)
{
    using namespace std::literals::string_literals;
    auto start = sStr1;
    auto end = sStr2;
    std::regex base_regex(start + "(.*)" + end);
    auto example = oStr;
    std::smatch base_match;
    std::string matched;
    if (std::regex_search(example, base_match, base_regex)) {
    if (base_match.size() == 2) {
        matched = base_match[1].str();
        }
       rStr = matched;
    }
}

Beispiel:

   string strout;
    getBtwString("it's_12345bb2","it's","bb2",strout); 
    getBtwString("it's_12345bb2"s,"it's"s,"bb2"s,strout); // second solution

Überschriften:

#include <regex> // second solution
#include <string.h> 

1187020cookie-checkC++ Get String zwischen zwei Trennzeichen String

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

Privacy policy