![]() |
Home | Libraries | People | FAQ | More |
For complicated regular expressions, dealing with numbered captures can be a pain. Counting left parentheses to figure out which capture to reference is no fun. Less fun is the fact that merely editing a regular expression could cause a capture to be assigned a new number, invaliding code that refers back to it by the old number.
Other regular expression engines solve this problem with a feature called named captures. This feature allows you to assign a name to a capture, and to refer back to the capture by name rather by number. Xpressive also supports named captures, both in dynamic and in static regexes.
For dynamic regular expressions, xpressive follows the lead of other popular
regex engines with the syntax of named captures. You can create a named capture
with "(?P<xxx>...)"
and refer back to that capture with "(?P=xxx)"
.
Here, for instance, is a regular expression that creates a named capture
and refers back to it:
// Create a named capture called "char" that matches a single // character and refer back to that capture by name. sregex rx = sregex::compile("(?P<char>.)(?P=char)");
The effect of the above regular expression is to find the first doubled character.
Once you have executed a match or search operation using a regex with named
captures, you can access the named capture through the
object using the capture's name.
match_results<>
std::string str("tweet"); sregex rx = sregex::compile("(?P<char>.)(?P=char)"); smatch what; if(regex_search(str, what, rx)) { std::cout << "char = " << what["char"] << std::endl; }
The above code displays:
char = e
You can also refer back to a named capture from within a substitution string.
The syntax for that is "\\g<xxx>"
.
Below is some code that demonstrates how to use named captures when doing
string substitution.
std::string str("tweet"); sregex rx = sregex::compile("(?P<char>.)(?P=char)"); str = regex_replace(str, rx, "**\\g<char>**", regex_constants::format_perl); std::cout << str << std::endl;
Notice that you have to specify format_perl
when using named captures. Only the perl syntax recognizes the "\\g<xxx>"
syntax. The above
code displays:
tw**e**t
If you're using static regular expressions, creating and using named captures
is even easier. You can use the
type to create a variable that you can use like mark_tag
s1
, s2
and friends, but with a
name that is more meaningful. Below is how the above example would look using
static regexes:
mark_tag char_(1); // char_ is now a synonym for s1 sregex rx = (char_= _) >> char_;
After a match operation, you can use the mark_tag
to index into the
to access the named capture:
match_results<>
std::string str("tweet"); mark_tag char_(1); sregex rx = (char_= _) >> char_; smatch what; if(regex_search(str, what, rx)) { std::cout << what[char_] << std::endl; }
The above code displays:
char = e
When doing string substitutions with
,
you can use named captures to create format expressions
as below:
regex_replace()
std::string str("tweet"); mark_tag char_(1); sregex rx = (char_= _) >> char_; str = regex_replace(str, rx, "**" + char_ + "**"); std::cout << str << std::endl;
The above code displays:
tw**e**t
![]() |
Note |
---|---|
You need to include |