C++正则表达式:将\d\s(替换为\d*(。

3
在字符串ss中,我该如何用"3*("替换"3 ("?(需要适用于任意数字。)
std::string result;
std::string ss;
static const std::regex nn1 ("\\)(\\d)");
static const std::regex nn2 ("(\\d)(\\s\\()");

ss = "5 + 3 (2 + 1)";
std::regex_replace (std::back_inserter(result), ss.begin(), ss.end(), nn2, "\d*($2");
std::cout << result << "\n";

编译器错误行7 - '\d' 是一个未被识别的转义序列。(我尝试在那里使用'\\d'.)

MS Visual Studio 2013

(这不是提出的问题的重复,因为这涉及更改字符而不是插入字符,并且这处理不能在替换字符串中使用正则表达式并且必须解决该限制的方法,选择的答案通过先使用$1来解决这个问题。)


我有一个一般性的请求:当你得到帮助时,请用点赞和接受答案来回报。 - Wiktor Stribiżew
可能是c++ regex_replace not doing intended substitution的重复问题。 - AndyG
Mike,我链接的dup实际上是你的另一个几乎完全相同的问题。 - AndyG
@AndyG:现在,需要捕获的字符串部分不同了。不确定我们是否应该将其视为重复。 - Wiktor Stribiżew
@stribizhev:这个问题是之前打算提出的问题的一个小的概括。 - AndyG
这是一个非常不同的问题,因为它涉及更改字符而不是插入字符,并且您必须克服无法在替换字符串中使用正则表达式模式的限制。 - user2120235
3个回答

0

对于这样的字符串(但只有一个括号),您可以使用以下正则表达式作为更一般的方法:

(\d)\s?\(

并替换为:

$1\*\(

$1 将匹配你的正则表达式中括号前的数字,即第一个分组。

编辑:在 c++ 中,您可以执行以下操作:

std::regex_replace (std::back_inserter(result), ss.begin(), ss.end(), nn2, "$1\*\("); 

谢谢。我没有意识到在C++中不能使用/d进行替换,而你必须绕过这个问题。这个更改可以工作: std::regex_replace(std::back_inserter(result), ss.begin(), ss.end(), nn2, "$1\*\("); - user2120235
另外,我不需要更改任何其他行。 - user2120235
@MikeSmith 没问题!我已经加入了你的建议! ;) - Mazdak

0

编译器错误是因为您在C++字符串中使用了转义序列\d,但实际上它并不存在。更糟糕的是,您试图在替换字符串中使用正则表达式模式,这不是您想要的。您需要在其中使用一些字面字符串,并使用类型为$1$ + 数字引用捕获组在正则表达式模式中)的反向引用。

请使用此代码:

std::string result;
std::string ss;
static const std::regex nn1 ("\\)(\\d)");
static const std::regex nn2 ("(\\d+)\\s*\\(");

ss = "5 + 3 (2 + 1)";
std::regex_replace (std::back_inserter(result), ss.begin(), ss.end(), nn2, "$1*(");
std::cout << result << "\n";

输出:

enter image description here

nn2 变量将保存正则表达式 (\d+)\s*\(,该表达式将捕获:

  • (\d+) - 数字,1个或多个,但尽可能多地放在第1组中。
  • \s*\( - 0个或多个空格,以及一个字面上的左圆括号。

在替换时,我们将引用第一组作为 $1。无需转义 *(


不,将正则表达式模式用于替换字符串正是我想要的,但似乎在C++中使用该函数无法实现,所以您必须绕过这种限制。谢谢您的帮助。您的回答确实提供了帮助,但我选择的答案更接近我的问题。 - user2120235
你选择的答案如果在 3( 之间有超过1个空格,将会失败。无论如何,您可以在SO上点赞以表达感激之情 :) 另一个“怨恨”:Kasra在他的原始答案中使用了\1而不是$1,在他看到我的答案后,他进行了更新。 - Wiktor Stribiżew
好的。你改了很多东西。我不需要d+,也不需要s*,因为在这个问题规范中永远只会有一个空格。无论如何,我现在有足够的投票权来点赞了,所以我点了,因为你的答案确实包含了解决方案。谢谢。 - user2120235
谢谢。另外,请考虑接受我的答案,网址为http://stackoverflow.com/questions/29992601,这样问题就可以“完成”了。 - Wiktor Stribiżew

0
try {
    ResultString = TRegEx::Replace(SubjectString, "\"(\\d+) \\(\"", "\"$1*(\"", TRegExOptions() << roSingleLine << roMultiLine);
} catch (ERegularExpressionError *ex) {
    // Syntax error in the regular expression
}

正则表达式解释:

"(\d+) \("

Options:  Exact spacing; Dot matches line breaks; ^$ match at line breaks; Numbered capture

Match the character “"” literally «"»
Match the regex below and capture its match into backreference number 1 «(\d+)»
   Match a single character that is a “digit” «\d+»
      Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the character “ ” literally « »
Match the character “(” literally «\(»
Match the character “"” literally «"»

"$1*("

Insert the character “"” literally «"»
Insert the text that was last matched by capturing group number 1 «$1»
Insert the character string “*("” literally «*("»

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接