2

我很难为以下问题找出一个正则表达式(遗憾的是,我几乎没有经历过):

  • 以给定前缀开头的文本(假设它是ab4
  • text 有 4 个 4 个字符块的主体(这就是4inab4代表的内容),每个块都可以是 ASCII 字母数字、空格、括号、连字符或点(基本上是a-zA-Z0-9 ()-.)。示例:abcd, .b a, ,b(a.)都是有效的单块。
  • 文本正文可以为空(ab4是唯一的内容)或最多包含四个块(ab4xxxx, ab4xxxxxxxx, ab4xxxxxxxxxxxx,ab4xxxxxxxxxxxxxxxxx有效字符)
  • 文本以 CR 结尾(回车 - \r\n)。结尾算作终止字符,不是正文的一部分

到目前为止,我想出了

.*ab4([a-zA-Z0-9 ()-.]{4}){1,4}\\r\\n.*

在我将它添加到我的 C++ 代码之前,我使用正则表达式 101来验证我的正则表达式。但是,如果我输入

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 '

4

1 回答 1

2

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

  • 提取整个匹配项,捕获您需要进一步处理的部分,以及
  • 将每个捕获拆分为 4 个字符的部分。

第一个提取正则表达式将是

ab4((?:[a-zA-Z0-9 ().-]{4}){1,4})\\r\\n
   ^                 ^          ^

请注意,我在您感兴趣的部分周围添加了捕获括号,连字符位于字符类的末尾。

使用该模式从文本中提取所有匹配项。

然后将其拆分match.captured(1)长度为 4 的子字符串。您实际上不需要在此步骤中使用正则表达式,因为字符串在第一个正则表达式步骤中已经预先验证。

于 2017-11-07T09:00:08.173 回答