Vim正则表达式与前瞻和后缀匹配而不会破坏前瞻行为

时间:2018-04-30 17:48:32

标签: regex vim

考虑一下vim中的两个不同的高亮匹配 模式1。     syn match match1 / \ $ [^ $] + \ $ / 匹配$foo$$bar$$123$ 模式2。     syn匹配match2 /(\ w + \ |(\ $ [^ \ $] + \ $)\ @ =)+ __ / 我希望它与foo$bar$__匹配,但不是$bar$ 问题是Pattern1将与Pattern2冲突。 我正在尝试使用Positive Lookahead绕过Pattern2中的Pattern1, 但是前缀__(双下划线)会破坏正向前瞻的行为。 我该如何解决这个问题?或者我做错了什么!?

更新

抱歉说不好。

模式1匹配由两个美元符号包围的任何字符串

syn match match1 /\$[^$ ]\+\$/
-> $foo$, $bar$

模式2匹配任何带有双下划线的字符串结尾但匹配仍然匹配,但排除任何匹配为Pattern1的字符串。

syn match match2 /\(\w\+\|\(\$[^\$]\+\$\)\@=\)\+__/
-> hello__, world__

所以问题是当我添加任何与模式1相关的字符串

hello$foo$__

在这种情况下。我想问你好和__匹配模式1(连续)

但也让$ foo $与模式2匹配。

1 个答案:

答案 0 :(得分:1)

我认为你不明白前瞻是什么。看起来你要做的就是匹配一个字符串,但跳过它的一部分:

foo$bar$___
^^^~~~~~^^^

...标记为^的部分形成匹配(不连续),标记为~的部分将被跳过。

正则表达式无法做到这一点。正则表达式总是匹配连续的字符串。

前瞻是什么让它“向前看”:它像往常一样匹配子正则表达式,但不会移动字符串中的当前位置。根据您放在前瞻的位置,这可以让您检查匹配结束后的文本,或者确保同时使用两个正则表达式匹配相同的字符串(尽管后者也可以在vim中使用\&完成)。

示例:

\%(foo\)\@=bar

这永远不会匹配。它要求接下来的三个字符同时为foobar,这是不可能的。

我认为你要找的是重叠的比赛。 Vim直接支持这个:

syn match match1 /\$[^$ ]\+\$/
syn match match2 /\%(\w\|\$[^$ ]\+\$\)\+__/ contains=match1

我们在此处说match2的匹配项可以包含match1的匹配项。这为您提供了所需的突出显示。