C++ 如何将正则表达式中组的每个迭代作为一个单独的组来获取?

C++ 如何将正则表达式中组的每个迭代作为一个单独的组来获取?,c++,regex,qregularexpression,C++,Regex,Qregularexpression,对于以下问题,我很难找到正则表达式(遗憾的是,我几乎没有使用过正则表达式): 以给定前缀开头的文本(假设它是ab4) 文本有一个由4个字符组成的4块体(这就是ab4中的4所代表的),每个字符可以是ASCII字母数字、空格、括号、连字符或点(基本上是a-zA-Z0-9()-.)。示例:abcd,.ba,,b(a.)都是有效的单个块 文本正文可以是空的(ab4是唯一的内容)或最多包含四个块(ab4xxx,ab4xxxxx,ab4xxxxxxxx,ab4xxxxxxxxxxx,其中x为有效字符) 文

对于以下问题,我很难找到正则表达式(遗憾的是,我几乎没有使用过正则表达式):

  • 以给定前缀开头的文本(假设它是
    ab4
  • 文本有一个由4个字符组成的4块体(这就是
    ab4
    中的
    4
    所代表的),每个字符可以是ASCII字母数字、空格、括号、连字符或点(基本上是
    a-zA-Z0-9()-.
    )。示例:
    abcd
    .ba
    b(a.)
    都是有效的单个块
  • 文本正文可以是空的(
    ab4
    是唯一的内容)或最多包含四个块(
    ab4xxx
    ab4xxxxx
    ab4xxxxxxxx
    ab4xxxxxxxxxxx
    ,其中
    x
    为有效字符)
  • 文本以CR结尾(回车符-
    \r\n
    )。结尾被视为终止字符,不属于正文的一部分
到目前为止,我已经想出了

.*ab4([a-zA-Z0-9 ()-.]{4}){1,4}\\r\\n.*
<>我在将我的正则表达式添加到我的C++代码之前,用它来验证我的正则表达式。但是如果我输入

ab4aaa bbb ccc ddd \r\n 
我得到以下数据:

  • 完全匹配:

    0-25'ab4aaa bbb ccc ddd\r\n'

  • 第1组:

    15-19“ddd”

正则表达式验证器告诉我

重复捕获组将只捕获最后一次迭代。放 捕获重复组周围的组以捕获所有迭代或 如果您对数据不感兴趣,请使用非捕获组

但坦率地说,我不知道这意味着什么。我尝试了
([a-zA-Z0-9()-.]{4}{1,4})
,变化不大

我正在寻找一个更好的分组,即将4个块分开作为单独的组。对于上面的例子,我期望

  • 完全匹配:

    0-25'ab4aaa bbb ccc ddd\r\n'

    • 第1组:
    0-3“aaa”

    • 第1组:
    4-7“bbb”

    • 第3组:
    8-11“ccc”

    • 第4组:
    12-15“ddd”


您使用的PCRE正则表达式引擎(带有
QRegularExpression
)不支持每个组的捕获堆栈,因此您必须使用两步方法:

  • 提取整个匹配项,捕获需要进一步处理的部分,以及
  • 将每个捕获拆分为4个字符的部分
第一个提取正则表达式是

ab4((?:[a-zA-Z0-9 ().-]{4}){1,4})\\r\\n
   ^                 ^          ^
注意,我在您感兴趣的部分周围添加了捕获括号,连字符位于character类的末尾

使用该模式从文本中删除


然后将捕获的
匹配项(1)
拆分为。此步骤实际上不需要使用正则表达式,因为在第一个正则表达式步骤中字符串已经过预验证。

您使用的正则表达式库是什么<代码>标准::正则表达式?澄清一下:在每个正则表达式中,结果匹配对象中的组数与模式中的捕获组数相同。这个数字是常数。您可能使用的是捕获集合。但是,只有3个正则表达式引擎支持该功能。我使用的是Qt附带的
QRegularExpression
类。到目前为止,我确信它支持组,可以通过
QList QRegularExpression::capturedTexts()
函数返回组,第一次捕获始终是完全匹配的,后续捕获是单个组。好的,这意味着您使用的PCRE不支持每个组的捕获堆栈,因此,您必须使用两步方法:1)提取整个匹配项捕获需要进一步处理的部分,以及2)较小的正则表达式,该正则表达式将匹配每个匹配项中捕获的数据中所需模式的多次出现。第一个是ab4((?:[a-zA-Z0-9().-]{4}{1,4})\\r\\n(注意连字符在末尾),第二个是
[a-zA-Z0-9().-]{4}
甚至
{4}
或者检查是否有其他方法将一个字符串拆分为Qt中的4字符字符串的子字符串。因此基本上我可以遍历整个字符串,应用我的正则表达式,如果找到一个(在末尾),我将其切掉,然后重复,直到没有更多的匹配项为止?你迭代查找所有匹配项,每次找到匹配项时,抓取
captured(1)
,然后运行。我认为唯一需要指出的是,您可以使用
QStringRef
来获取较小的4个字符长的块,而不是使用
std::substr
。它只是创建了一个更可读的代码,因为您不需要来回转换为
std::string
。我还在最后一个括号后面和
\\r
前面添加了一个
,因为否则将不包括案例
ab4\r\n
。很好。此外,您可以使用
\\R
匹配任何换行序列。嗯,实际上它不起作用。-\u试着在
{4}
中输入8或16(可能也有更高的数字)而不是4,然后在
ab4aaa bbb ccc ddd\r\n
字符串上测试它。它每次都有效。为了确保它不是我的额外
我删除了它,但问题仍然存在。顺便说一句
\\R
是不必要的,因为字符串总是以CR结尾。
ab4aaa bbb ccc ddd
结尾有空格吗?