【问题标题】:Regex with overlapping and repeating具有重叠和重复的正则表达式
【发布时间】:2020-04-22 15:27:19
【问题描述】:

假设我有一个字符串s = "ACBCAACBCBCAB"。我想找到一个正则表达式,它可以给我所有长度为 3 的字符串,这些字符串在 s 中重复至少 2 次(可能重叠)。例如,字符串s 给出:

ACB(2 次)

CBC(3次)

BCA(2次)

我正在考虑使用regex = "(?=([ABC]{3}))\1{1,}",但不太正确。我正在使用 C++。

谢谢。

PS:问题中的s 就是一个例子。我想要一个适用于一般s 的正则表达式(子字符串,长度为 3,仍然重复至少 2 次)。又如s = "ABABA"时,子串为"ABA"

【问题讨论】:

    标签: c++ regex


    【解决方案1】:

    如果你匹配了正则表达式

    (?=(.{3}))(?=.+\1)
    

    到字符串

    ZABABABCACACABAABADEFGDEF
    

    将有 7 个匹配项(空字符串),其中每个匹配项的捕获组 1 的内容是如下所示的 3 个字母字符串。

    ZABABABCACACABAABADEFGDEF
    0123456789012345678901234
     ABA
      BAB
       ABA
           CAC
            ACA
                ABA
                      DEF
    

    Demo

    每个这三个字符的字符串后跟相同的三个字符,这些字符在字符串的其余部分中至少出现一次。结果,重复了一些匹配。因此我们必须提取数组的唯一值

    ["ABA", "BAB", "ABA", "CAC", "ACA", "ABA", "DEF"] 
    

    获得

    ["ABA", "BAB", "CAC", "ACA", "DEF"] 
    

    作为在字符串中至少出现两次的 3 个字符的字符串。

    (?=(.{3})) 的第一个匹配发生在正则表达式引擎的内部指针紧邻 Z 之前,并且捕获组 1 包含 ZAB。我们现在在字符串后面查找捕获组 1 的内容的匹配项,从 Z 右侧开始之后。因此,我们需要.+,而不是(?=.+\1) 中的.*。没有(?=.+\1)的匹配,所以匹配失败。由于环视不消耗任何字符,因此正则表达式引擎的内部指针没有移动。

    然后内部指针向前移动一个字符,到紧挨第一个A 之前的位置,捕获组1 的内容变为ABA。从第二个 A 开始,在偏移量 3 处找到匹配,之后内部指针再次向前移动一个字符,到紧挨第一个 B 之前的位置,并重复该过程。

    假设正则表达式

    (?=(.{3})).+\1
    

    改为使用。在得出ZAB 在字符串中仅出现一次的结论后,指针位于第一个A 之前,并且捕获组1 包含ABA.+\1 然后匹配 ABABABCACACABAABA(表明 ABA 重复)。但是,内部指针随后被移动到第一个 D 之前的位置,导致我们错过了几个重复的 3 字符字符串。使.+ 不贪婪((?=(.{3})).+?\1 会有所帮助,但我们仍然会错过BABACA

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 2017-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-13
      • 2020-11-26
      相关资源
      最近更新 更多