vim替换字符串带斜杠_Vim:正则表达式匹配一个字符串

到目前为止,所有给出的答案对我来说都是错误的,因为它们执行的是贪婪匹配。在多次出现“否”的行中,它们将匹配最后一个:

YES YES YES YES no YES YES no YES

^^^^^^^^^^^^^^^^^^^^^^^^^^^

但是,将所有内容匹配为一个字符串的目的通常是在第一次出现时就停止:

YES YES YES YES no YES YES no YES

^^^^^^^^^^^^^^^^

为此,请使用non-greedy正则表达式,例如:

.\{-}\(no\)\@=

\{-}是乘数*的非贪婪替代(请参阅:help non-greedy)。 \@=是一个积极的前瞻性,它将检查是否跟随“ no”,但不会将其包括在比赛中(请参阅:help /\@=)。

作为一个旁注,“将所有内容匹配到一个字符串”的常见方案是将一个带有开始和结束定界符的表达式匹配。例子:

C风格的字符串文字"string literal";

C ++样式的注释// comment\n(其结束定界符是换行符);

正则表达式/regex/。

在许多此类情况下,结束分隔符实际上可能在要匹配的表达式内出现escaped。例如:

C样式的字符串文字可能包含双引号字符,在这种情况下,它必须像\"中那样转义。

在C ++注释中,以反斜杠开头的换行符将被忽略,其副作用是注释在下一行继续。

正则表达式可以包含斜杠;在对正则表达式的语法过于简化的情况下,我们可以假定所有此类出现都像在\/中那样被转义了(这是不正确的,例如/[abc/]/也是一个有效的Vim regex,它与任何“ a”,“ b”,“ c”,“ /”之间的字符)。

因此,我们必须优化正则表达式,以使其不会在结束分隔符的转义出现时停止。

让我们从错误的正则表达式开始,该正则表达式匹配开始定界符“ start”和结束定界符“ stop”之间的任何内容(由于\@<=和正前瞻\@=):

\(start\)\@<=\_.\{-}\(stop\)\@=

任何“停止”事件都将停止,即使逃脱也是如此:

test start test \stop test stop test

^^^^^^^

要解决此问题,我们可以将\_.(与任何字符,包括换行符匹配)替换为\_[^\\](与任何字符但反斜杠匹配)和\\\_.(匹配反斜杠,后跟任意字符)。这意味着任何未转义的反斜杠将被解释为转义序列的开始。反斜杠本身可以转义,因此\\stop是转义的反斜杠,后跟一个真正的结束定界符。

这是盲文表达形式:

\(start\)\@<=\(\_[^\\]\|\\\_.\)\{-}\(stop\)\@=

和一些测试:

test start test \stop test stop test

^^^^^^^^^^^^^^^^^

test start test \\stop test stop test

^^^^^^^^

test start test \\\stop test stop test

^^^^^^^^^^^^^^^^^^^

你可能感兴趣的:(vim替换字符串带斜杠)