From today's advent of code we had input that could be a list of several bags.
A string like "3 drab lime bags, 1 drab plum bag, 2 vibrant tomato bags, 1 plaid blue bag."; was for example in my input.
What I did to solve this: split it among the ',', and then apply std::regex bag_regex("([0-9]+) (\\w+ \\w+) bag"); to each of these substrings.
Now I tried if I could do it maybe in one sitting or something, and tried to use https://en.cppreference.com/w/cpp/regex/regex_token_iterator instead.
Sample code:
std::string test = "3 drab lime bags, 1 drab plum bag, 2 vibrant tomato bags, 1 plaid blue bag.";
std::regex bag_regex_it("[0-9]+ \\w+ \\w+");
std::copy(std::sregex_token_iterator(test.begin(), test.end(), bag_regex_it, -1),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(std::cout, "\n"));
What I actually get in my output:
bags,
bag,
bags,
bag.
Is there any way to get it already in groups (the number count, and the color description)? My guess is that proper lambda usage would help here, but I have no idea how to do this. Ideal result would be a std::vector of like std::pair<int, std::string> containing the parsed information, but this code is beyond me.
You could use the last parameter in regex_token_iterator as an array of subgroups (considering 2 groups (number and color) you want).
The following snippet doesn't do any error checking and assumes you input string is valid:
using Pair = std::pair<int, std::string>;
Pair p;
const int subgroups[] = {1,2};
std::vector < Pair> results; // Your desired result
std::regex_token_iterator<std::string::iterator> c
{ test.begin(), test.end(), regex_it, subgroups };
std::regex_token_iterator<std::string::iterator> rend;
while (c!=rend) {
// Do some sort of error handling here
p.first = std::stoi(*c++);
p.second = *c++;
results.push_back(p);
}
std::cout << results.size(); // 4
Demo here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With