我有这个纯文本文件:
1 : Foo Bar Bar Baz
2 : The dog The cat the hamster
3 : the dog the cat the hamster
4 : The dog the cat the hamster The Doors
我想强调所有重复的词语。
我修改了这个解决方案:
/\(\<\w\+\>\)\zs[ w]\+\1
这适用于第一行(第二个栏突出显示)但这不能解决以下问题:
第2行:它突出显示第二个&#34;&#34;,但不是小写&#34;&#34;
第3行:它只突出显示&#34;&#34;
的第一次重复第4行:它只突出显示第二个&#34;&#34; (第一个重复的单词),但不是第二个&#34;&#34; (另一个重复的词)
PS:只是为了它,一个侧面问题:是否有可能突出显示相邻行中的重复单词,以便在3行的范围内看到相同单词的重复?
提前谢谢
答案 0 :(得分:3)
效果稍好一点:
/\(\<\w\+\>\).\{-}\zs\<\1\>
的变化:
[ w]\+
替换为.\{-}
(在这对词之间匹配任何字符;非贪婪量词)。\zs
。\1
围绕\<...\>
;这些锚点不自动从捕获子模式继承。不幸的是,还有一个问题;第三个&#34;&#34;第3行和第2行&#34;&#34;由于与另一场比赛重叠,第4行不匹配。这可以通过使用后视模式\@<=
(可能会降低性能)而不是\zs
来解决:
/\%(\<\1\>.\+\)\@<=\(\<\w\+\>\)
让这个工作是一个试验和错误;它需要:
\%(...\)
代替\(...\)
)\+
而不是{-}
)以下两种模式均可使用以下可选添加项:
\c
添加到模式中以防止不区分大小写。.
替换为\_.
,以便在换行符中找到重复字词。请注意第二种模式,跨线匹配的范围有限。后视搜索只能向后搜索一行。这是设计使然,以避免严重的性能问题。因此,只有当两个单词在同一行上时,或者在紧随其后的行上才会识别出重复的单词。
如果我们按照Qeole的例子来匹配第一个单词而不是最后一个单词,事情会变得更容易;我们可以使用前瞻,它没有与后视相关的大多数缺点。这是完整的,不区分大小写和跨行匹配:
/\<\(\w\+\)\>\(\_.\+\<\1\>\)\@=\c
我们甚至可以将这两种模式与\|
结合起来,将两者包含在搜索结果中的第一个和最后一个单词中:
/\%(\<\1\>\_.\+\)\@<=\(\<\w\+\>\)\|\<\(\w\+\)\>\(\_.\+\<\1\>\)\@=\c
Peter Rincker的重要提示:由于NFA正则表达式引擎中的错误,lookbehind在某些版本的VIM 7.4中可能无效。您可以强制它使用旧的回溯引擎,并通过预先添加模式\%#=1
来获得所需的结果。有关详细信息,请参阅:h NFA
。不要在VIM 7.3及更早版本中使用。
/\%#=1\%(\<\1\>\_.\+\)\@<=\(\<\w\+\>\)\|\<\(\w\+\)\>\(\_.\+\<\1\>\)\@=\c
答案 1 :(得分:1)
免责声明:这是一个近似的答案,收集我在@ Ruud的答案和OP的问题的评论中所写的内容。
首先,这是解决案例问题的快速解决方法(The
与the
):
:set ignorecase
但是Ruud建议使用\c
可能会更好。
然后,这里有一个关于重复单词的出现,包括第一次出现在线,但排除最后一个的提议:
/\(\<\w\+\>\)\ze.\{-}\1
这与Ruud的解决方案非常相似(即使我自己得到它)。如果有人对最后一次出现的修复有兴趣,我有兴趣学习它。
由于Ruud - 再次 - 也指出,一种解决方案可能是使用Vim \@<=
。这个\@<=
正则表达式原子的文档中有一个有趣的例子:
/\1\@<=,\([a-z]\+\)
应与,abc
中的abc,abc
匹配,但我无法使此示例正常工作(在我看来\1
仍为空)。
我不知道附带问题,对不起。