正则表达式正向后视+负向前视

Regular expressions positive lookbehind + negative lookahead

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

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

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

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

我正在考虑以某种方式使用正面回顾和负面展望来获取重复单词的最后一个实例:(?<=.*(?!.*(\w+).*).*)\b\b
(在我脑子里是翻译成"a word that had been matched before and won't match again")

嗯,不幸的是它对我不起作用。

是否可以通过这种方式使用正向后视和负向前视?
我的正则表达式可以修复吗?
我试图用 C# 解决它。

这不是作业

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

(\b\w+\b)(?:(?=.*?\b\b)|(?<=\b\b.*?))

Demo

推理如下:

  • 匹配一个词:(\b\w+\b)

  • 然后:(?:...|...)

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

      回溯中的第二个 </code> 匹配之前匹配的单词。第一个<code>才是真正的重复。


已编辑问题的答案:

如果只想匹配第一次出现的重复词,我们可以稍微改变一下上面的模式:

(\b\w+\b)(?=.*?\b\b)(?<!\b\b.*?)

Demo

现在的逻辑是:

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

    (与之前相同,只是有一个负面的回顾)