2

Vim 中的哪个正则表达式将匹配no.以下字符串中的所有字符?

foo, bar, and baz, no. 13, qux

换句话说,匹配必须是foo, bar, and baz,

我是正则表达式的新手,我在这里对 Stack Overflow 进行了研究,一个建议是.+?(?= no.). 但它似乎只适用于正则表达式的正则(perl?)风格,而不是在 Vim 中。

请帮忙。

也许有一个更简单的解决方案来解决我想要实现的目标。我的最终目标是放入foo, bar, and baz大括号,并且我计划使用涉及正则表达式的全局替换命令。

4

4 回答 4

5

vim中的这个正则表达式应该做

.*\zeno

例如,您在您的线路上执行此操作:

s/.*\zeno//

该行将更改为:

no. 13, qux

编辑

刚刚看到你的“最终目标”,你可以使用正则表达式:

:s/.*\zeno/{&}

如果您不想换行逗号:

:s/.*\ze, no/{&}
于 2013-11-12T16:41:44.360 回答
4

我的最终目标是将“foo、bar 和 baz”放在大括号中

你可以试试

:s/\v(.*)(, no\.)/{\1}\2/
于 2013-11-12T17:09:30.733 回答
1

这应该这样做:

.*\( no[.]\)\@=

在单词中,直到匹配“no.”的字符集的所有字符。匹配前瞻\@=,执行“否”检查。

于 2013-11-12T17:12:17.703 回答
0

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

YES YES YES YES no YES YES no YES
^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

YES YES YES YES no YES YES no YES
^^^^^^^^^^^^^^^^

为此,请使用非贪婪正则表达式,例如:

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

\{-}是乘数的非贪心替代方案*(见:help non-greedy)。\@=是一个积极的前瞻,它将检查“否”是否跟随但不会将其包含在匹配中(请参阅:help /\@=)。


作为旁注,“将所有内容匹配到某个字符串”的常见场景是匹配带有开始和结束分隔符的表达式。例子:

  • C 风格的字符串文字"string literal"
  • C++ 风格的注释// comment\n(其结束分隔符是换行符);
  • 正则表达式/regex/

在许多这样的情况下,关闭分隔符实际上可能在要匹配的表达式中出现转义。例如:

  • AC 风格的字符串文字可能包含双引号字符,在这种情况下,它必须像\".
  • 在 C++ 注释中,前面有反斜杠的换行符将被忽略,其副作用是注释在下一行继续。
  • 正则表达式可能包含斜杠;在对正则表达式语法的一种过于简单化的方法中,我们可以假设所有这些出现都被转义为\/(这是不正确的,例如,/[abc/]/它也是一个有效的 Vim 正则表达式,它匹配“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
          ^^^^^^^^^^^^^^^^^^^
于 2018-08-09T14:22:13.707 回答