C++ regex both matches and groups

I have the following regex: ([0-9]+)\/([0-9]*)\/([0-9]*) (properly escaped in my code). As you can see, this has three capture groups: one that must contain at least one number, and two additional groups (that may be empty).

I'm trying to run this over a string that should produce three matches for the entire regex. For example:

f 5/1/1 1/2/1 4/3/1

In this case, the result of the regex should be the following:

Match 1: 5/1/1, Group 1: 5, Group 2: 1, Group 3: 1

Match 2: 1/2/1, Group 1: 1, Group 2: 2, Group 3: 1

Match 3: 4/3/1, Group 1: 4, Group 2: 3, Group 3: 1

However, the way I understand it, C++11 can't return both the matches and the groups.

If I were to run the following code,

std::smatch matchs;
std::regex_search("f 5/1/1 1/2/1 4/3/1", matches "([0-9]+)\\/([0-9]*)\\/([0-9]*)");

matches would have 10 elements: matches[0] would be everything from 5 to the end, and matches[1]-matches[9] would have the capture groups. But I'm not only trying to get the groups, I'm trying to get each of the matches (preferably with the groups organized by match).

As in: matches[1] would have 5/1/1, matches[2] would have 1/2/1, and matches[3] would have 4/3/1. Then, in something like (for example): groups[n] would have the corresponding group. Or, if possible, matches[1].groups would have the groups that were found within the match.

Is this correct? And/or is there some way to easily get both matches and capture groups?

Note: This is not a duplicate as other questions seem to be asking either about multiple matches or groups, not both at the same time.

1 answer

  • answered 2019-09-15 21:17 sln

    The way it is done is to iterate using regex_search() which has
    many prototypes.

    Regex iterator stuff reverts to this behind the scenes.

    Here you go.
    There are many more answers to how to use regex in C++,
    just let me know.

    std::string::const_iterator start = str.begin();
    std::string::const_iterator end   = str.end();
    std::smatch m;
    
    std::regex rx( "([0-9]+)/([0-9]*)/([0-9]*)" );
    
    while ( std::regex_search( start, end, m, rx ) )
    {
        std::string sWholeMatch = m[0].str();
        std::string sGrp1 = m[1].str();
        std::string sGrp2 = m[2].str();
        std::string sGrp3 = m[3].str();
    
        int lenGrp1 = sGrp1.length(); 
        int lenGrp2 = sGrp2.length(); 
        int lenGrp3 = sGrp3.length(); 
    
        start = m[0].second;
    }