C ++ 11正则表达式:在替换字符串中捕获组后的数字

C++11 regex: digit after capturing group in replacement string

我的 regex_replace 表达式在替换字符串中的“0”字符之前使用组 $1,如下所示:

#include <iostream>
#include <string>
#include <regex>

using namespace std;

int main() {
    regex regex_a( "(.*)bar(.*)" );
    cout << regex_replace( "foobar0x1", regex_a, "xNUM" ) << endl;
    cout << regex_replace( "foobar0x1", regex_a, " 0xNUM" ) << endl;
}

输出为:

xNUM
foo 0xNUM

我试图获得没有中间空格的输出 foo0xNUM

如何保护组名 $1 不受替换字符串中下一个字符的影响?

我试图找到一种简单地转义 space 之类的方法,这样它就不会打印出来,但我做不到。

但是,您尝试添加的位可以简单地附加到正则表达式输出的末尾:

cout << regex_replace( "foobar0x1", regex_a, "" ) << "0xNUM" << endl;

上面一行会给你你想要的输出。

您可以指定 $n$nn 来引用捕获的文本,因此您可以使用 $nn 格式(此处为 </code>)以避免抓取<code>0.

cout << regex_replace( "foobar0x1", regex_a, "0xNUM" ) << endl;

Guvante 已经解决了这个问题。

但是,行为是否根据规范明确定义?

从结论说起。 是的,该解决方案具有明确定义的行为。

C++ 规范

format_default 的文档指定了解释格式字符串的 ECMA 规则,指向 ECMA-262 的第 15.5.4.11 节。

ECMA-262 规范

根据 Table 22 在 Section 15.5.4.11 of ECMA-262 specification

$n

The nth capture, where n is a single digit in the range 1 to 9 and $n is not followed by a decimal digit. If n ≤ m and the nth capture is undefined, use the empty String instead. If n > m, the result is implementation-defined.

$nn

The nnth capture, where nn is a two-digit decimal number in the range 01 to 99. If nn ≤ m and the nnth capture is undefined, use the empty String instead. If nn > m, the result is implementation-defined.

变量m在同一节的上一段中定义:

[...] Let m be the number of left capturing parentheses in searchValue (using NcapturingParens as specified in 15.10.2.1).

问题中的替换字符串"xNUM"

回到问题中的代码:

cout << regex_replace( "foobar0x1", regex_a, "xNUM" ) << endl;

由于 </code> 后跟 <code>0,因此必须将其解释为第二条规则 $nn,因为第一条规则禁止任何数字跟随 $n。但是,由于该模式只有 2 个捕获组 (m = 2) 并且 10 > 2,因此根据规范,行为是 实现定义的

通过比较 Firefox 37.0.1 中功能等效的 JavaScript 代码的结果,我们可以看到实现定义子句的效果:

> "foobar0x1".replace(/(.*)bar(.*)/g, "xNUM" )
< "foo0xNUM"

如您所见,Firefox 决定将 </code> 解释为采用第一个捕获组 <code> 的值,然后是固定字符串 0。根据规范,在 $nn 子句中的条件下,这是一个有效的实现。

Guvante 回答中的替换字符串:"0xNUM"

同上,使用了$nn子句,因为$n子句禁止后面跟任何数字。由于中的01小于capturing groups的个数(m=2),行为是明确的,即在replacement中使用capturing group 1的内容。

因此,Guvante 的回答将 return 在任何投诉的 C++ 编译器上得到相同的结果。