我正在尝试搜索包含一组单词的任何排列的行(不区分大小写)。例如,如果我对单词foo
和bar
感兴趣,我会希望匹配以下file
中的前四行而不是最后四行:
Foo and bar.
Bar and foo.
The foo and the bar.
The bar and the foo.
Foobar.
Barfoo.
The foobar.
The barfoo.
看了this post后,我意识到我可以在perl
中构建这样的内容:
perl -n -e 'print if (/\bfoo\b.*?\bbar\b/i || /\bbar\b.*?\bfoo\b/i)' file
正确匹配前四行。或者,使用this post建议的前瞻构造,可以使用稍微简洁的代码进行匹配:
perl -n -e 'print if (/(?=.*\bfoo\b)(?=.*\bbar\b)/i)' file
但是,我不能弄清楚如何用vim
正则表达式语法来编写这些语法,我发现它比perl
正则表达式语法更加拜占。我使用搜索功能(vim
或/
)在?
中尝试了许多不同的表达式,但它们都没有产生成功匹配。我意识到(?=string)
使用perl
和vim
而不是\(string\)\@=
使用的string\&
语法。
然而,各种尝试,例如:
\c\(foo\)\@=\(bar\)@=
\c\(foo\)\@=\.*\(bar\)@=
\cfoo\&bar\&
(其中\c
用于不区分大小写的匹配)都不成功。
有人可以演示正确的vim
语法吗?
答案 0 :(得分:5)
尝试:\c.*\<foo\>.*\&.*\<bar\>.*
。这应该匹配前四行中的每一行。
你最接近\c\(foo\)\@=\(bar\)@=
,但是因为你不想要,例如foobar
,barfoo
以匹配使用单词匹配开头/结尾的必要性:\<\>
。
使用\&
简化了模式。
如果您不需要来自该模式的整个行匹配,只需匹配任何匹配的行,您可以通过删除尾随.*
来简化此正则表达式。模式中的碎片:\c.*\<foo\>\&.*\<bar\>
答案 1 :(得分:2)
尝试以下方法:
/^\c\(.*\<foo\>\)\@=\(.*\<bar\>\)\@=/
这与Perl的前瞻版本相同,\@=
使前一个元素或组成为正面的前瞻。 \<
和\>
是与\b
等效的vim,\c
启用不区分大小写的匹配。我添加了^
锚点,因此它只匹配每一行。