问题
Perl has the e
regex modifier which allows Perl code rather than just a string to formulate the replacement: http://perldoc.perl.org/perlretut.html#Search-and-replace Though that example is not the greatest as there are switches to accomplish this. For those of you who understand Perl here's an example that makes more sense:
$string = "StackOverflow user: Jonathan Mee";
$string =~ s/:\s*(.*)$/$1 == "Jonathan Mee" ? ": ".$1." is AWESOME!" : ": ".$1." is ???"/e;
print $string; #Will print "StackOverflow user: Jonathan Mee is AWESOME!"
Is there a regex_replace
variant in C++ that will allow me to do something similar? As in code inline for the replacement.
回答1:
regex_replace has 6 different overloads. The fmt
argument is used the same way for each of them:
A string with the replacement for each match. This may include format specifiers and escape sequences that are replaced by the characters they represent.
Each of the 6 overloads also sport a flags
argument which is used to control, "how fmt
is formatted." The fmt
related options are:
format_default
: Default formatting
Uses the standard formatting rules to replace matches (those used by ECMAScript's replace method).format_sed
sed formatting
Uses the same rules as the sed utility in POSIX to replace matches.format_no_copy
No copy
The sections in the target sequence that do not match the regular expression are not copied when replacing matches.format_first_only
First only
Only the first occurrence of a regular expression is replaced.
Note that none of the fmt
overloads, nor the flags
support in-line code. So the answer is: No, there is no variant of regex_replace
that supports in-line code.
However if you were willing to use a STD algorithm in conjunction with regex_iterator, you could use a lambda to accomplish in-line code.
const string foo("StackOverflow user: Jonathan Mee");
vector<string> bar;
transform(regex_iterator<string::const_iterator>(foo.cbegin(), foo.cend(), regex(".*:\\s*(.*)")),
regex_iterator<string::const_iterator>(),
back_inserter(bar),
[](const smatch& i){auto result = i.str();
if (!result.empty()){
result += (i.str(1) == "Jonathan Mee" ? " is AWESOME!" : " is ???");
}
return result;});
As you can see a lambda is usable in the transform
taking in the current regex_iterator
's smatch
. This is very extensible to multi-line strings, in the example of string foo("StackOverflow user: Jonathan Mee\nStackOverflow user: user0");
the output would be:
StackOverflow user: Jonathan Mee is AWESOME!
StackOverflow user: user0 is ???
Clearly there are some trade-offs working with just an smatch
versus regex_replace
. Where str(1)
falls within str()
is not specified. Here I take advantage of the fact that it is right at the end of foo
rather than somewhere that has to be found in the middle of foo
. But it should be mentioned that the same difficulty befalls Perl's e
-modifier, so I think this is pretty much on par.
来源:https://stackoverflow.com/questions/29367546/is-there-a-variant-of-regex-replace-that-supports-inline-code