【问题标题】:Vim regex matching with lookahead and suffix without destroy the lookahead behaviorVim 正则表达式匹配前瞻和后缀而不破坏前瞻行为
【发布时间】:2018-04-30 17:48:32
【问题描述】:

想想 vim 中两种不同的高亮匹配 模式 1。 同步匹配 match1 /\$[^$ ]+\$/ 匹配$foo$$bar$$123$ 模式 2。 同步匹配 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$__

在这种情况下。我想要 hello AND __ 匹配模式 1(连续)

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

【问题讨论】:

  • 如果我给你一个 PCRE 正则表达式,你能把它转换成 vim 吗?
  • 嗯,在 PCRE 中,没有任何 boundary 添加信息,就是这个(?:\w+\$[^$ ]+\$__|\$[^$ ]+\$)。真的不需要前瞻。根据需要转换为 vim 语法。
  • 如果你想在$aa$之后完全禁止__(除非与foo之前匹配),在\$[^$ ]+\$子句之后添加断言,就像这样(?:\w+\$[^$ ]+\$__|\$[^$ ]+\$(?!__))
  • 我不明白你的模式 2。你能用英语描述它应该匹配什么吗?
  • 对于您可以使用的第一个语法模式:/\v\$[^$ ]+\$(_)@!/。这将匹配美元符号之间没有下划线的单词(例如:$foo$)。对于第二种模式:/\v\w+\$[^$]+\$__/。这将匹配一个单词,然后是美元符号之间的单词,然后是双下划线(例如:foo$bar$__

标签: regex vim


【解决方案1】:

我认为您不了解前瞻的作用。看起来你想要做的是匹配一个字符串,但跳过它的一部分:

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

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

这对于正则表达式是不可能的。一个正则表达式总是匹配一段连续的字符串。

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

例子:

\%(foo\)\@=bar

这永远无法匹配。它要求后面三个字符同时是foobar,这是不可能的。


我认为您正在寻找的是重叠匹配。 Vim 直接支持这个:

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

这里我们说match2 的匹配可以包含match1 的匹配。这将为您提供所需的突出显示。

【讨论】:

    猜你喜欢
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    相关资源
    最近更新 更多