I am using Named Capture Groups with Boost Regex / Xpressive.
I would like to iterate over all submatches, and get both the value and KEY of each submatch (i.e. what["type"]).
sregex pattern = sregex::compile( "(?P<type>href|src)=\"(?P<url>[^\"]+)\"" );
sregex_iterator cur( web_buffer.begin(), web_buffer.end(), pattern );
sregex_iterator end;
for( ; cur != end; ++cur ){
smatch const &what = *cur;
//I know how to access using a string key: what["type"]
std::cout << what[0] << " [" << what["type"] << "] [" << what["url"] <<"]"<< std::endl;
/*I know how to iterate, using an integer key, but I would
like to also get the original KEY into a variable, i.e.
in case of what[1], get both the value AND "type"
*/
for(i=0; i<what.size(); i++){
std::cout << "{} = [" << what[i] << "]" << std::endl;
}
std::cout << std::endl;
}
After looking at this for more than an hour, I feel fairly safe saying, "it can't be done captain". Even in the boost code, they iterate over the private named_marks_ vector when doing the lookup. It is just not setup to allow that. I'd say the best bet would be to iterate over the ones you think should be there and catch the exception for those that aren't found.
With Boost 1.54.0 this is even more difficult because the capture names are not even stored in the results. Instead, Boost just hashes the capture names and stores the hash (an
int
) and the associated pointers to the original string.I've written a small class derived from
boost::smatch
that saves capture names and provides an iterator for them.The class accepts the regular expression containing the named capture groups in its constructor. Use the class like so: