简体   繁体   中英

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]. 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.

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:

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. Implementations of explode() will break a string into multiple strings based on a given delimiter. 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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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