Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match regex multiple times in one std::string

Tags:

c++

regex

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.

like image 369
SinisterMJ Avatar asked Feb 27 '26 23:02

SinisterMJ


1 Answers

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

like image 191
P0W Avatar answered Mar 01 '26 21:03

P0W



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!