regex_replace 是否有支持内联代码的变体?
Is There a Variant of regex_replace that Supports Inline Code?
Perl 具有 e
正则表达式修饰符,它允许 Perl 代码而不仅仅是字符串来制定替换:http://perldoc.perl.org/perlretut.html#Search-and-replace 虽然这个例子不是最好的,因为有一些开关可以实现这个。对于那些了解 Perl 的人来说,这里有一个更有意义的例子:
$string = "Whosebug user: Jonathan Mee";
$string =~ s/:\s*(.*)$/ == "Jonathan Mee" ? ": ".." is AWESOME!" : ": ".." is ???"/e;
print $string; #Will print "Whosebug user: Jonathan Mee is AWESOME!"
C++ 中是否有 regex_replace
变体允许我做类似的事情?如替换代码内联。
regex_replace
有 6 种不同的重载。 fmt
参数对每个参数的使用方式相同:
A string with the replacement for each match.
This may include format specifiers and escape sequences that are replaced by the characters they represent.
6 个重载中的每一个还带有一个 flags
参数用于控制,"how fmt
is formatted." fmt
相关选项是:
format_default
: 默认格式
使用标准格式规则替换匹配项(ECMAScript 的替换方法使用的规则)。
format_sed
sed 格式化
使用与 POSIX 中的 sed 实用程序相同的规则来替换匹配项。
format_no_copy
没有复制
替换匹配时不复制目标序列中与正则表达式不匹配的部分。
format_first_only
第一只
仅替换第一次出现的正则表达式。
请注意,fmt
重载的 none 和 flags
都不支持内联代码。所以答案是:不,regex_replace
没有支持内联代码的变体。
但是,如果您愿意将 STD 算法与 regex_iterator
结合使用,则可以使用 lambda 来完成内联代码。
const string foo("Whosebug 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;});
如您所见,lambda 在 transform
中可用,用于当前 regex_iterator
的 smatch
。这对于多行字符串非常可扩展,在 string foo("Whosebug user: Jonathan Mee\nWhosebug user: user0");
的示例中,输出将是:
Whosebug user: Jonathan Mee is AWESOME!
Whosebug user: user0 is ???
显然,仅 smatch
与 regex_replace
之间存在一些权衡。未指定 str(1)
属于 str()
的位置。在这里,我利用了它就在 foo
末尾的事实,而不是必须在 foo
中间找到的某个地方。但应该提到的是,同样的困难也降临在 Perl 的 e
-修饰符上,所以我认为这非常相似。
Perl 具有 e
正则表达式修饰符,它允许 Perl 代码而不仅仅是字符串来制定替换:http://perldoc.perl.org/perlretut.html#Search-and-replace 虽然这个例子不是最好的,因为有一些开关可以实现这个。对于那些了解 Perl 的人来说,这里有一个更有意义的例子:
$string = "Whosebug user: Jonathan Mee";
$string =~ s/:\s*(.*)$/ == "Jonathan Mee" ? ": ".." is AWESOME!" : ": ".." is ???"/e;
print $string; #Will print "Whosebug user: Jonathan Mee is AWESOME!"
C++ 中是否有 regex_replace
变体允许我做类似的事情?如替换代码内联。
regex_replace
有 6 种不同的重载。 fmt
参数对每个参数的使用方式相同:
A string with the replacement for each match. This may include format specifiers and escape sequences that are replaced by the characters they represent.
6 个重载中的每一个还带有一个 flags
参数用于控制,"how fmt
is formatted." fmt
相关选项是:
format_default
: 默认格式
使用标准格式规则替换匹配项(ECMAScript 的替换方法使用的规则)。format_sed
sed 格式化
使用与 POSIX 中的 sed 实用程序相同的规则来替换匹配项。format_no_copy
没有复制
替换匹配时不复制目标序列中与正则表达式不匹配的部分。format_first_only
第一只
仅替换第一次出现的正则表达式。
请注意,fmt
重载的 none 和 flags
都不支持内联代码。所以答案是:不,regex_replace
没有支持内联代码的变体。
但是,如果您愿意将 STD 算法与 regex_iterator
结合使用,则可以使用 lambda 来完成内联代码。
const string foo("Whosebug 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;});
如您所见,lambda 在 transform
中可用,用于当前 regex_iterator
的 smatch
。这对于多行字符串非常可扩展,在 string foo("Whosebug user: Jonathan Mee\nWhosebug user: user0");
的示例中,输出将是:
Whosebug user: Jonathan Mee is AWESOME!
Whosebug user: user0 is ???
显然,仅 smatch
与 regex_replace
之间存在一些权衡。未指定 str(1)
属于 str()
的位置。在这里,我利用了它就在 foo
末尾的事实,而不是必须在 foo
中间找到的某个地方。但应该提到的是,同样的困难也降临在 Perl 的 e
-修饰符上,所以我认为这非常相似。