簡體   English   中英

如何從C ++中的字符串中提取子字符串?

[英]How to extract a substring from a string in C++?

我一直在尋找關於我要問的問題的成千上萬的問題和答案,但是我仍然沒有找到做我要解釋的方法的方法。

我有一個文本文件,我必須從中提取有關幾件事的信息,所有這些信息都采用以下格式:

"string1":"string2"

在那之后,有更多信息,我的意思是:

文本文件是這樣的:

LINE 1 XXXXXXXXXXXXXXXXXXXXXXXXXXXX“ string1”:“ string2” XXXXXXXXXXXXXXXXXXXXXXXXXX“ string3”:“ string4” XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ...('\\ n')

LINE 2 XXXXXXXXXXXXXXXXXXXXXXXXXXXX“ string5”:“ string6” XXXXXXXXXXXXXXXXXXXXXXXXXX“ string7”:“ string8” XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ...

XXX代表我不需要的無關信息,EntireString(在代碼示例中使用的字符串)存儲一行的所有信息,而不是文本文件的所有信息。

我必須首先找到string1的內容,並將string2的內容存儲到另一個沒有引號的字符串中。 問題是,當我到達最后一個報價時,我必須停下來,而且我不知道該怎么做。 我想我必須使用功能find()和substr(),但是盡管反復嘗試,但還是沒有成功。

我所做的是這樣的:

string extractInformation(string theEntireString)
{
  string s = "\"string1\":\"";    
  string result = theEntireString.find(s);
  return result;
}

但是這樣我想我將最后一個引號和其余字符串存儲到字符串中。

“ find”函數只為您提供匹配字符串的位置,以獲取需要使用“ subst”函數的結果字符串。 嘗試這個

string start,end;
start = theEntireString.substr(1,theEntireString.find(":")-2);
end = theEntireString.substr(theEntireString.find(":")+2,theEntireString.size()-1);

那會解決你的問題

祝你好運...

兩步:

首先,我們必須找到的位置:和拼接字符串分為兩個部分:

string first = theEntireString.substr(0, theEntireString.find(":"));
string second = theEntireString.substr(theEntireString.find(":") + 1);

現在,我們必須刪除""

string final_first(first.begin() + 1, first.end() - 1);
string final_second(second.begin() + 1, second.end() - 1);

假設鍵或值包含引號。 以下將在“:”之后輸出值。 如果在輸入字符串中有多個鍵值對,還可以在循環中使用它重復提取值字段,前提是您要記錄最后找到的實例的位置。

#include <iostream>
using namespace std;

string extractInformation(size_t p, string key, const string& theEntireString)
{
  string s = "\"" + key +"\":\"";
  auto p1 = theEntireString.find(s);
  if (string::npos != p1)
    p1 += s.size();
  auto p2 = theEntireString.find_first_of('\"',p1);
  if (string::npos != p2)
    return theEntireString.substr(p1,p2-p1);
  return "";
}

int main() {
  string data = "\"key\":\"val\" \"key1\":\"val1\"";
  string res = extractInformation(0,"key",data);
  string res1 = extractInformation(0,"key1",data);
  cout << res << "," << res1 << endl;
}

輸出:

val,val1
#include <regex>
#include <iostream>

using namespace std;

const string text = R"(
XXXXXXXXXXXXXXXXXXXXXXXXXXXX"string1":"string2"XXXXXXXXXXXXXXXXXXXXXXXXXX"string3"  :"string4" XXXXXXXXXXXXXXXXXXXXXXXXXXXX...
XXXXXXXXXXXXXXXXXXXXXXXXXXXX"string5":  "string6"XXXXXXXXXXXXXXXXXXXXXXXXXX"string7"  :  "string8" XXXXXXXXXXXXXXXXXXXXXXXXXXXX...
)";

int main() {
    const regex pattern{R"~("([^"]*)"\s*:\s*"([^"]*)")~"};
    for (auto it = sregex_iterator(begin(text), end(text), pattern); it != sregex_iterator(); ++it) {
        cout << it->format("First: $1, Second: $2") << endl;
    }
}

Output:

First: string1, Second: string2
First: string3, Second: string4
First: string5, Second: string6
First: string7, Second: string8

您不需要任何字符串操作。 我希望XXXXX不包含任何'“',因此您可以直接從文件中讀取兩個字符串:

ifstream file("input.txt");
for( string s1,s2; getline( getline( file.ignore( numeric_limits< streamsize >::max(), '"' ), s1, '"' ) >> Char<':'> >> Char<'"'>, s2, '"' ); )
    cout << "S1=" << s1 << " S2=" << s2 << endl;

一點幫助功能Char是:

template< char C >
std::istream& Char( std::istream& in )
{
    char c;
    if( in >> c && c != C )
        in.setstate( std::ios_base::failbit );
    return in;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM