【问题标题】:Vim multiline regex gives overlapping matchesVim 多行正则表达式给出重叠匹配
【发布时间】:2012-04-22 06:04:32
【问题描述】:

当我注意到我的贪婪多行正则表达式在 Vim 中给出重叠匹配时,我感到很惊讶。正则表达式旨在匹配整个文本块或连续的非空行。

正则表达式显然匹配了我期望的所有内容(突出显示看起来正确),但是当使用n 跳到下一个匹配而不是跳到下一个块时,它转到了当前块的下一行。

这是我使用的正则表达式(相当于大多数正则表达式引擎的 (.+\n){1,}):

\(.\+\n\)\{1,}

这应该至少匹配一个非空行,并且尽可能多的连续非空行,这是一个示例文本文件:

block 1
some stuff
more stuff

block 2
foo bar
baz qux

应用此正则表达式后 (/\(.\+\n\)\{1,}+Enter) 两个块正确突出显示,但我希望正则表达式只有两个匹配项,每个块一个。但是,当我按 n 前进到下一个正则表达式匹配时,似乎每个非空行都与正则表达式匹配,所以我的光标将从第一行开始, n 会把它带到第二行,然后是第三行,然后到块 2 的开头,等等。

如何更改我的正则表达式,以便我看到每个块的预期行为是单个匹配,以便 n 前进到下一个块,而不是下一行?强>

我也有兴趣了解此行为是否在文档中的某处,或者是否有更改此行为的选项。请注意,在搜索/替换中使用相同的正则表达式时,行为是我所期望的(替换只会应用两次,每个块一次)。

【问题讨论】:

    标签: regex vim vi


    【解决方案1】:

    以下正则表达式似乎有效:

    \(\%^\|^\n\)\zs\(.\+\n\)\+
    

    解释:

    \(             # start of group
      \%^          # beginning of file
        \|         # OR
      ^\n          # a blank line
    \)             # end of group
    \zs            # start matching here
    \(.\+\n\)\+    # at least one non-blank line
    

    通过使用very magic 选项,长度可以减少一点:

    \v(%^|^\n)\zs(.+\n)+
    

    期待看看是否有人能提出更短的解决方案!

    zigdon 的回答帮助我更好地理解了这种行为的原因。当 n 用于跳转到下一个匹配时,它会从光标的当前位置搜索正则表达式的第一个匹配,即使下一个匹配位置包含在上一个匹配中。这就是为什么将正则表达式锚定到块的开头似乎是必要的原因。

    感谢 Nolen Royalty 帮助我摆脱了第一组中不必要的前瞻。

    【讨论】:

    • 据我所知\(\%^\|^\n\)\zs\(.\+\n\)* 完成了同样的事情。不过,它仍然令人沮丧。
    • @NolenRoyalty 如果有几个连续的空行,你将匹配一些空行(零宽度匹配),但它确实引导我到\(\%^\|^\n\)\zs\(.\+\n\)\+,它没有同样的问题。还是很丑!
    【解决方案2】:

    由于您的匹配项说“匹配一个或多个非空行”,它当然可以在同一段落中匹配多次。要解决此问题,您可以指定光标应放在匹配的 end 处 - 这意味着下一个匹配将从段落的末尾开始。您可以使用 vim 中的 \zs 零宽度字符来执行此操作:

    \zs     Matches at any position, and sets the start of the match there: The
            next char is the first char of the whole match. |/zero-width|
    

    所以你的比赛会变成:

    \(.\+\n\)\{1,}\zs
    

    【讨论】:

    • 这使我可以跳到每个块的末尾,这对于正则表达式的简单性来说是很好的,但如果可能的话,我希望将整个块包含在匹配中。
    • 该块将包含在匹配中,只是光标将定位在它的末尾。还是你的意思是别的?
    • 我所说的“包含在匹配中”的意思是,如果您在搜索/替换中使用相同的正则表达式,则匹配中包含的所有内容都将被替换。另一个等效含义是“突出显示的文本”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    • 2010-09-24
    • 1970-01-01
    相关资源
    最近更新 更多