给定字符串"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
(在我的脑海中被翻译为“一个以前已经匹配过且不再匹配的单词”)

好吧,不幸的是,这对我不起作用。

这样可以使用正向后看和负向前看吗?
我的正则表达式可以固定吗?
我试图用C#解决它。

这不是功课

最佳答案

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

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


Demo

理由如下:


匹配单词:(\b\w+\b)
然后是:(?: ... | ... )


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

后面的第二个\1与之前匹配的单词匹配。第一个\1是真实副本。





回答已编辑的问题:

如果您只想匹配重复出现的单词的第一次出现,我们可以对上述模式进行一些更改:

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


Demo

现在的逻辑是:


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

(与之前相同,但后面带有负向外观)

10-04 22:19