RE2 嵌套正则表达式组匹配

RE2 Nested Regex Group Match

我有一个 RE2 正则表达式如下

const re2::RE2 numRegex("(([0-9]+),)+([0-9])+");
std::string inputStr;
inputStr="apple with make,up things 2,412,3.00");
RE2::Replace(&inputStr, numRegex, "");
cout << inputStr;

预计

apple with make,up,things 24123.00

我试图删除识别号码中的,</code>只会匹配<code>312而不匹配412部分。想知道如何提取组中的递归模式。

请注意,RE2 不支持前瞻(参见 ),我发现的解决方案都使用前瞻。

基于RE2的解决方案

由于 RE2 不支持 lookarounds,因此没有纯粹的单通道正则表达式解决方案。

你可以有一个解决方法(像往常一样,当没有可用的解决方案时):用 (\d),(\d) 正则表达式和 </code> 替换字符串两次:</p> <pre><code>const re2::RE2 numRegex(R"((\d),(\d))"); std::string inputStr("apple with make,up things 2,412,3.00"); RE2::Replace(&inputStr, numRegex, ""); RE2::Replace(&inputStr, numRegex, ""); // <- Second pass to remove commas in 1,2,3,4 like strings std::cout << inputStr;

基于C++ std::regex的解决方案:

您可以使用

删除数字之间的逗号
std::string inputStr("apple with make,up things 2,412,3.00");
std::regex numRegex(R"((\d),(?=\d))"); 
std::cout << regex_replace(inputStr, numRegex, "") << "\n";
// => apple with make,up things 24123.00

参见C++ demo. Also, see the regex demo here

详情:

  • (\d) - 捕获组 1 (</code>):一个数字</li> <li><code>, - 逗号
  • (?=\d) - 正向前瞻,需要紧邻当前位置右侧的数字。

在您尝试的模式中,您正在重复外部组 (([0-9]+),)+,它将包含最后一次迭代的值,它可以匹配一个 1+ 数字和一个逗号。

最后一次迭代将捕获 412, 并且只匹配 312,


您正在使用 regex,但作为替代方案,如果您有 boost 可用,您可以使用 \G 锚点,它可以获得迭代匹配断言上一个结束位置匹配并替换为空字符串。

(?:$|\G(?!^))\d+\K,(?=\d)

模式匹配:

  • (?:非捕获组
    • $ 匹配 $
    • |
    • \G(?!^) 声明上一场比赛结束时的位置,而不是开始
  • )关闭非捕获组
  • \d+\K 匹配 1+ 个数字,忘记到目前为止匹配的是什么
  • ,(?=\d) 匹配一个逗号并断言一个数字直接在右边

Regex demo

#include<iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;

int main()
{
    std::string inputStr = "apple with make,up things 2,412,3.00";
    boost::regex numRegex("(?:\$|\G(?!^))\d+\K,(?=\d)");  
    std::string result = boost::regex_replace(inputStr, numRegex, "");
    std::cout << result << std::endl;
}

输出

apple with make,up things 24123.00