给定一个字符串 "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))
推理如下:
匹配一个词:
(\b\w+\b)
然后:
(?:
...|
...)
- 确保它稍后再次出现:
(?=.*?\b\1\b)
或者之前已经发生过:
(?<=\b\1\b.*?\1)
那一秒
\1
在lookbehind中匹配之前匹配的单词。第一个\1
是真正的副本。
- 确保它稍后再次出现:
编辑问题的答案:
如果你只想匹配第一次出现的重复词,我们可以稍微改变一下上面的模式:
(\b\w+\b)(?=.*?\b\1\b)(?<!\b\1\b.*?\1)
现在的逻辑是:
- 匹配一个词:
(\b\w+\b)
- 确保它再次出现:
(?=.*?\b\1\b)
并确保它之前没有发生:
(?<!\b\1\b.*?\1)
(和以前一样,只是有一个负面的回顾)
关于c# - 正则表达式正向后视+负向前视,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31350659/