C ++ 11 regex:在替换字符串中捕获组后的数字

时间:2015-04-22 22:07:58

标签: c++ regex c++11 regex-group

我的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, "$10xNUM" ) << endl;
    cout << regex_replace( "foobar0x1", regex_a, "$1 0xNUM" ) << endl;
}

输出结果为:

xNUM
foo 0xNUM

我试图在没有中间空格的情况下获得输出foo0xNUM

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

2 个答案:

答案 0 :(得分:5)

Guvante已为此问题提供a solution

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

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

C ++规范

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

ECMA-262规范

根据Section 15.5.4.11 of ECMA-262 specification

中的表22
  

$n

     

第n次捕获,其中n是1到9范围内的单个数字,$n后面没有十进制数字。如果n≤m并且第n次捕获未定义,请改用空字符串。如果n> m,结果是实现定义的。

     

$nn

     

第n次捕获,其中nn是01到99范围内的两位十进制数。如果nn≤m且未定义第n个捕获,则使用空字符串。如果nn> m,结果是实现定义的。

变量m在前一段中的同一部分中定义:

  

[...]设m是searchValue中左侧捕获括号的数量(使用15.10.2.1中指定的NcapturingParens)。

问题"$10xNUM"

中的替换字符串

回到问题中的代码:

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

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

我们可以通过比较Firefox 37.0.1中功能相同的JavaScript代码的结果来看到implementation-defined子句的效果:

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

正如您所看到的,Firefox决定将$10解释为获取第一个捕获组$1的值,然后是固定字符串0。根据规范,这是$nn子句中的条件下的有效实现。

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

与上面相同,使用$nn子句,因为$n子句禁止跟随任何数字。由于$01中的01小于捕获组的数量(m = 2),因此行为是明确定义的,即使用替换中捕获组1的内容。

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

答案 1 :(得分:0)

我试图找到一种简单地逃避空间或某种东西的方法,这样就不会打印出来,但我无法做到。

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

pwd <- as.raw(c(0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64))
login("username", rawToChar(pwd))

以上行会为您提供所需的输出。