如何捕获多达N次的重复组?

时间:2018-10-17 09:15:37

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

我想捕获一个字符串中的数字链,但最多只能捕获3次。

此后的任何数字链均应忽略。例如:

T441_S45/1 => 441 45 1 007_S4 => 007 4 41_445T02_74 => 41 445 02

我已经尝试过(\d+){1,3},但这似乎不起作用...

有任何提示吗?

1 个答案:

答案 0 :(得分:2)

您可以匹配并捕获用任意数量的非数字和字符串的其余部分分隔的前三位数字,并用对这些组的反向引用替换:

^\D*(\d+)(?:\D+(\d+))?(?:\D+(\d+))?.*

或者,如果字符串可以是多行,

^\D*(\d+)(?:\D+(\d+))?(?:\D+(\d+))?[\s\S]*

替换字符串看起来像$1 $2 $3

详细信息

  • ^-字符串的开头
  • \D*-0 +个非数字
  • (\d+)-第1组:一个或多个数字
  • (?:\D+(\d+))?-可选的非捕获组匹配:
    • \D+-超过1个非数字
    • (\d+)-第2组:一个或多个数字
  • (?:\D+(\d+))?-另一个可选的非捕获组匹配:

    • \D+-一个或多个非数字
    • (\d+)-第3组:一个或多个数字
  • [\s\S]*-字符串的其余部分。

请参见regex demo

C++ demo

#include <iostream>
#include <regex>
using namespace std;

int main() {
    std::vector<std::string> strings;
    strings.push_back("T441_S45/1");
    strings.push_back("007_S4");
    strings.push_back("41_445T02_74");

    std::regex reg(R"(^\D*(\d+)(?:\D+(\d+))?(?:\D+(\d+))?[\s\S]*)");
    for (size_t k = 0; k < strings.size(); k++)
    {
        std::cout << "Input string: " << strings[k] << std::endl;
        std::cout << "Replace result: " 
                     << std::regex_replace(strings[k], reg, "$1 $2 $3") << std::endl;
    }
    return 0;
}

输出:

Input string: T441_S45/1
Replace result: 441 45 1
Input string: 007_S4
Replace result: 007 4 
Input string: 41_445T02_74
Replace result: 41 445 02