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

时间:2014-02-22 17:02:30

标签: c++ string

我一直在寻找关于我要问的问题的数千个问题和答案,但我仍然没有找到方法去做我将要解释的事情。

我有一个文本文件,我必须从中提取有关几件事的信息,所有这些文件都采用以下格式:

"string1":"string2"

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

文本文件是这样的:

第1行 XXXXXXXXXXXXXXXXXXXXXXXXXXXX “字符串1”: “字符串2” XXXXXXXXXXXXXXXXXXXXXXXXXX “STRING3”: “串,4” ... XXXXXXXXXXXXXXXXXXXXXXXXXXXX( '\ n')

第2行 XXXXXXXXXXXXXXXXXXXXXXXXXXXX “STRING5”: “string6” XXXXXXXXXXXXXXXXXXXXXXXXXX “string7”: “string8” XXXXXXXXXXXXXXXXXXXXXXXXXXXX ...

XXX代表我不需要的不相关信息,而theEntireString(代码示例中使用的字符串)存储单行的所有信息,而不是文本文件的所有信息。

我必须首先找到string1的内容,并将string2的内容存储到另一个没有引号的字符串中。问题是当我到达最后一个引号时我必须停止,我不知道这是怎么做到的。我想我必须使用函数find()和substr(),但尽管反复尝试过,但我没有成功。

我所做的是这样的事情:

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

但是这样我想我会在字符串中存储最后一个引号和字符串的其余部分。

5 个答案:

答案 0 :(得分:1)

“find”函数只是给你匹配字符串的位置,以获得你需要使用“subst”函数的结果字符串。试试这个

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

这将解决你的问题

最好的运气......

答案 1 :(得分:0)

两个步骤:

首先我们必须找到:的位置并将字符串拼接成两部分:

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);

答案 2 :(得分:0)

假设键或值包含引号。以下将输出“:”之后的值。如果在输入字符串中有多个键值对,则可以在循环中使用它来重复提取值字段,前提是您保留最后找到的实例的位置记录。

#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

答案 3 :(得分:0)

#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

答案 4 :(得分:0)

您不需要任何字符串操作。我希望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;
}