正则表达式正面看后面+负向前瞻

时间:2015-07-10 21:36:46

标签: c# regex lookbehind negative-lookahead

给定一个字符串"A B C a b B"我希望匹配重复的单词(无论大小写)。预期的结果将匹配" a"和" b" (最后一次出现A和B)或" A"和" B" (第一次出现)

编辑:我想只匹配单词的第一个或最后一个出现

我知道通过拆分字符串并计算每个标记(降低该情况)可以更好地回答这个问题 但是,我想尝试制定一个正则表达式来帮助我找到这些单词,仅仅是为了练习。

我的第一个尝试是:(?=\b(\w+)\b.*\b(\1)\b)(\1)
但是它匹配第一个A,第一个B和第二个b(A B b)。

我想以某种方式使用带有负面预测的正面后视来获取重复单词的最后一个实例:(?<=.*(?!.*(\w+).*)\1.*)\b\1\b
(在我的脑海中翻译为&#34;之前已经匹配并且再次赢得比赛的单词&#34;)

嗯,不幸的是,它并不适合我。

是否有可能以这种方式使用积极的后视和负面预测? 我的正则表达式可以修复吗? 我试图用C#来解决它。

这不是作业

1 个答案:

答案 0 :(得分:1)

有趣的谜题。这是我的解决方案:

//div[@class='ncatstories']/a[count(h3)>0]/@href

Demo

推理如下:

  • 匹配单词:(\b\w+\b)(?:(?=.*?\b\1\b)|(?<=\b\1\b.*?\1))

  • 然后:(\b\w+\b) ... (?: ... |

    • 确保稍后再次发生:)
    • 或者之前已经发生过:(?=.*?\b\1\b)

      后视镜中的第二个(?<=\b\1\b.*?\1)与之前匹配的单词相匹配。第一个\1是真实副本。

回答编辑过的问题:

如果您只想匹配重复单词的第一个匹配项,我们可以稍微改变上述模式:

\1

Demo

现在的逻辑是:

  • 匹配单词:(\b\w+\b)(?=.*?\b\1\b)(?<!\b\1\b.*?\1)
  • 确保它再次出现:(\b\w+\b)
  • 并确保之前没有发生:(?=.*?\b\1\b)

    (与之前的情况相同,除了负面的背后)