代码之家  ›  专栏  ›  技术社区  ›  jevakallio

regex中的重叠匹配

  •  30
  • jevakallio  · 技术社区  · 17 年前

    我似乎找不到这个问题的答案,我想知道这个问题是否存在。简化示例:

    考虑一个字符串“nn nn”,在这里我想找到“nn”的所有匹配项,也就是那些相互重叠的匹配项。所以regex将提供以下3个匹配项:

    1. 神经网络 神经网络
    2. n 神经网络 n
    3. 神经网络 神经网络

    我意识到这并不是regex的真正含义,但考虑到在现实中,匹配必须使用模式而不是文字字符串来完成,因此,手动遍历字符串并对其进行分析似乎是一个非常糟糕的代码。

    3 回复  |  直到 17 年前
        1
  •  20
  •   Community Mohan Dere    9 年前

    可能的解决方案是使用 positive look behind :

    (?<=n)n
    

    它将为您提供以下结束位置:

    1. *******
    2. n*n*****n
    3. n**n*****

    如前所述 Timothy Khouri A 积极的展望 更直观

    我更喜欢他的提议 (?=nn)n 更简单的形式:

    (n)(?=(n))
    

    也就是说 第一位置 你想要的字符串 并捕获第二组n(2) .

    这是因为:

    • 任何有效的正则表达式都可以在lookahead中使用。
    • 如果包含捕获括号,则 将保存回溯引用 .

    所以组(1)和组(2)将捕获“n”表示的任何内容(即使它是一个复杂的regex)。

        2
  •  23
  •   Jan Goyvaerts    17 年前

    在捕获组中使用lookahead是可行的,但是会使regex变得更慢、更复杂。另一种解决方案是告诉regex.match()方法下一次匹配尝试应该从哪里开始。试试这个:

    Regex regexObj = new Regex("nn");
    Match matchObj = regexObj.Match(subjectString);
    while (matchObj.Success) {
        matchObj = regexObj.Match(subjectString, matchObj.Index + 1); 
    }
    
        3
  •  1
  •   PhiLho    17 年前

    对于afaik,没有一种纯粹的regex方法可以立即做到这一点(即返回您请求的三个捕获而不返回循环)。

    现在,您可以找到一次模式,并在搜索中循环,从偏移开始(找到位置+1)。应该结合使用regex和简单代码。

    [编辑]太好了,当我基本上说简的表演时,我被否决了…
    [编辑2]要清楚:简的回答更好。不是更精确,但肯定更详细,它值得选择。我只是不明白为什么我的被否决了,因为我仍然认为其中没有任何错误。没什么大不了的,只是烦人而已。