简体   繁体   English

通过多个定界符在C ++中解析字符串

[英]Parsing strings in C++ by multiple delimiters

I have a string object that is something like: 我有一个类似的字符串对象:

string test = "
[3, 4, 8, 10, 10]\n[12]\n[12, 10,\n 20]
"

And am trying to parse it into the 3 separate arrays equaling [3, 4, 8, 10, 10], [12], and [12,10, 20]. 并试图将其解析为3个单独的数组,它们分别等于[3、4、8、10、10],[12]和[12,10,20]。 I have parsed Comma separated integers into an array before but how do I go about parsing this one. 我之前已经将逗号分隔的整数解析为一个数组,但是如何解析这个整数。 Unfortunately the data I have can have newlines mid array otherwise I would use the "getline" function(when reading the file into the string) and simply ignore the brackets. 不幸的是,我拥有的数据可以在数组中间有换行符,否则我将使用“ getline”功能(将文件读入字符串时)而忽略括号。

It seems like I need to first get each array into its own string delimited by brackets, and then parse each of those by comma delimination into an array of integers. 看来我需要首先将每个数组放入用方括号分隔的自己的字符串中,然后通过逗号分隔将每个数组解析为整数数组。 Would this work? 这行得通吗?

If so, how do I split up the string by brackets into a previously unknown number of other strings? 如果是这样,如何将括号中的字符串分割成以前未知的其他字符串?

You can use streams and std::getline() for this as std::getline() takes a delimiter as a parameter: 您可以为此使用流和std::getline() ,因为std::getline()采用分隔符作为参数:

int main()
{
    std::string test = "[3, 4, 8, 10, 10]\n[12]\n[12, 10,\n 20]";

    // make data a stream (could be a std::ifstream)
    std::istringstream iss(test);

    // working vars
    std::string skip, item;

    // between square braces
    // skip to the opening '[' then getline item to the closing ']'
    while(std::getline(std::getline(iss, skip, '['), item, ']'))
    {
        // item = "3, 4, 8, 10, 10"

        // store numbers in a vector (not array)
        std::vector<int> v;

        // convert item to a stream
        std::istringstream iss(item);

        // separated by commas
        while(std::getline(iss, item, ','))
            v.push_back(std::stoi(item));

        // display the results
        std::cout << "list:" << '\n';
        for(auto i: v)
            std::cout << "\t" << i << '\n';
    }
}

Output: 输出:

list:
    3
    4
    8
    10
    10
list:
    12
list:
    12
    10
    20

If you have already read the whole thing into a string, the following should work: 如果您已经将整个内容读入一个字符串,则应该可以执行以下操作:

#include <iostream>
#include <string>

using namespace std;

int main() {
  string test = "[3, 4, 8, 10, 10]\n[12]\n[12, 10,\n 20]";
  size_t start = 0;  // first position in the string

  // find the first occurance of "]"
  size_t pos = test.find("]");

  while ( pos != string::npos ) {
    // move to position after "]"
    // so it is included in substring
    pos += 1;

    // create a substring
    string subStr = test.substr(start, pos-start);

    // remove newlines from new string
    size_t newLinePos = subStr.find("\n");
    while ( newLinePos != string::npos ) {
      subStr.erase(newLinePos,1);
      newLinePos = subStr.find("\n");
    }

   // here is the substring, like: [12, 10, 20]
    cout << "Substring: " << subStr << endl;

    // update start position for next substring
    start = pos;
    // find next occurrance of "]"
    pos = test.find("]", pos);
  }

}

One way to approach this is to use an explode() function. 一种解决方法是使用explode()函数。 Implementations of explode() will break a string into multiple strings based on a given delimiter. explode()的实现将基于给定的定界符将一个字符串分成多个字符串。 It's not the most efficient method, but it can make a lot of intuitive sense. 这不是最有效的方法,但是可以带来很多直观的感觉。

See: Is there an equivalent in C++ of PHP's explode() function? 请参阅: C ++中的PHP的explode()函数是否等效?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM