Regex vi中包含一组字符串的任何排列的匹配行

Regex vi中包含一组字符串的任何排列的匹配行,regex,perl,vim,Regex,Perl,Vim,我试图搜索包含一组单词的任何排列的行(不区分大小写)。例如,如果我对单词foo和bar感兴趣,我希望匹配以下文件中的前四行,但不匹配后四行: Foo and bar. Bar and foo. The foo and the bar. The bar and the foo. Foobar. Barfoo. The foobar. The barfoo. 看过之后,我意识到我可以在perl中构造类似的东西: perl -n -e 'print if (/\bfoo\b.*?\bbar\b/i

我试图搜索包含一组单词的任何排列的行(不区分大小写)。例如,如果我对单词
foo
bar
感兴趣,我希望匹配以下
文件中的前四行,但不匹配后四行:

Foo and bar.
Bar and foo.
The foo and the bar.
The bar and the foo.
Foobar.
Barfoo.
The foobar.
The barfoo.
看过之后,我意识到我可以在
perl
中构造类似的东西:

perl -n -e 'print if (/\bfoo\b.*?\bbar\b/i || /\bbar\b.*?\bfoo\b/i)' file
它只正确匹配前四行。或者,使用所建议的前瞻性构造,可以使用更简洁的代码进行匹配:

perl -n -e 'print if (/(?=.*\bfoo\b)(?=.*\bbar\b)/i)' file
然而,我不知道如何用
vim
regex语法编写这些代码,我发现它比
perl
regex语法更像拜占庭式。我使用搜索功能(
/
)在
vim
中尝试了许多不同的表达式,但没有一个能够成功匹配。我意识到,
vim
使用
\(string\)\@=
string\&
而不是
perl使用的
(?=string)
语法

但是,有多种尝试,例如:

  • \c\(foo\)\@=\(bar\)@=
  • \c\(foo\)\@=\.\(bar\)@=
  • \cfoo\&bar\&
(其中
\c
用于不区分大小写的匹配)均未成功

有人能演示一下正确的
vim
语法吗?

试试:
\c.*.\.\&.*.
。这应该与前四行中的每一行相匹配

您与
\c\(foo\)\=(bar\)@=
最接近,但由于您不希望例如
foobar
barfoo
匹配,因此必须使用单词的开头/结尾匹配:
\

使用
\&
可以稍微简化模式

如果您不需要该模式中的整行匹配,只需点击任何匹配的行,您可以通过删除模式中的后续
*
片段来简化此正则表达式:
\c.\\\\\&.\
尝试以下操作:

/^\c\(.*\<foo\>\)\@=\(.*\<bar\>\)\@=/
/^\c\(.\\)\@=\(.\\)\@=/

这与Perl中的前瞻版本相同,
\@=
使前一个元素或组成为正向前瞻
\
是与
\b
等效的vim,而
\c
支持不区分大小写的匹配。我添加了
^
锚定,因此它只会匹配每行一次。

谢谢,
^
锚定非常有用,因为没有锚定,行中的每个字符都被视为唯一匹配。您能告诉我如何添加可选后缀吗?说吧,我想和禁赛和禁赛比赛。我意识到我可以省略单词end boundary(
/^\c\(.\\)\@=\(..*\close),但是更多的转义:
\
谢谢,这两个词都正确匹配,并且每行只匹配一次。