Vim正则表达式:匹配直到空行

3
我正在尝试编写一个正则表达式,它将匹配包含“.wpd”的任何行,并匹配所有在此之后直到遇到一个空行的行(包括空行)。
这是我尝试过的正则表达式:
/\v^.*.wpd\_.\{-}^\s*$

然而,“包括换行符在内的所有字符”字符类\{-}后面的非贪婪运算符\{-}似乎不起作用。如果我使用
/\v^.*.wpd\_.*

我需要匹配下一行包含“.wpd”的所有行,可以使用*。然而,一旦将*更改为\{-},就无法匹配任何内容。

我做错了什么?谢谢!


看到你的回答了。你很接近了,只需要使用“anwhere”变量来表示行首和行尾字符即可。 - Ashutosh Jindal
4个回答

8
这个看起来可以用:
/\v^.*\.wpd\_.{-}\n\s*\n

太棒了,谢谢。我接受了Ingo的答案,因为他解释了我的代码为什么不起作用,但这是一个艰难的决定,我很感激你的回答。 - Justus Grunow

6

正则表达式中不能在内部使用原子符号^(同样适用于$),它只有在前面(后面)才有特殊含义;否则,它就会被视为普通字符。如果要匹配换行符,请在正则表达式中使用\n,如perreal的答案所示。


1
或者,使用锚点的任意位置等效项。因此,使用\_^\_$。因此,表达式可以简化为\v^.*.wpd\_.{-}\_^\s*\_$ - Ashutosh Jindal

1
(?s)[^\n\r]*\.wpd(.*?)\n{2}

(?s) - 打开“点匹配换行符”以跨行搜索

[^\n\r]* - 从行首开始,匹配任何不是换行符的内容

.wpd - 匹配“.wpd”

(.*?) - 非贪婪地匹配任何内容,包括换行符(因为我们之前打开了 (?s))

\n{2} - 直到找到两个连续的换行符,即空行

:)


0
以下是针对@perreal在上面的答案进行大量支持评论以及我自己更直观版本的回答。
让我们根据http://vimdoc.sourceforge.net/htmldoc/pattern.html#/magic来分析以下正则表达式。
/\v^.*\.wpd\_.{-}\n\s*\n
  1. \v(小写的v):这是“非常魔法”的运算符,表示在它后面的模式中,除了“0”-“9”,“a”-“z”,“A”-“Z”和“_”之外的所有ASCII字符都具有特殊含义。

    因此,在模式中不需要转义字符,如*^$,但是对于_具有特殊含义(例如修改.的行为以匹配换行符),则需要转义。因此,如果设置了\v,则需要使用\_才能使后者具有特殊含义。
    要真正欣赏到“非常魔法”简化表达式的程度,请将其与使用“非常NOmagic”(大写\V)的相同表达式进行比较:

    /\V\^\.\*.wpd\_\.\{-}\n\s\*\n(非常无魔法)与
    /\v^.*\.wpd\_.{-}\n\s*\n(非常魔法)

  2. ^.*\.wpd:贪婪地匹配任何东西(.*)从一行的开头(^)到.wpd

  3. \_.:匹配一个字符,可以是任何字符,包括换行符。
    请注意,如果设置了\v,则模式必须像上面提到的那样转义下划线。

  4. {-}:是*量词的非贪婪等效项。因此,.*BLAH匹配最多可能的字符直到BLAH,而.{-}BLAH将匹配最少可能的字符。要查看这个过程,请看一下这个(在这种情况下,我不得不使用?而不是{-},因为该正则表达式是PCRE):

    enter image description here

  5. \n\s*\n:匹配可能包含一个或多个空格或制表符的空行

  6. \_.{-}\n\s*\n:结合上述两个意思,表示
    匹配最少数量的字符,包括换行符(\_.),直到空行(\n\s*\n

  7. \v^.*\.wpd\_.{-}\n\s*\n:最后将它们组合起来,
    设置“非常魔法”运算符(可能允许通过不需要转义除了_以外的任何内容来简化模式),搜索包含.wpd的任何行,并匹配到最近的空行。


使用行尾和行首字符的变体版本

唯一的修改是用于表示空行的表达式。我发现将空行定义为以行首('^')和行尾('$')字符为基础很有用,但是在正则表达式中,它们只能分别用于开头和结尾。

对于上述用例,有一些变体可以在正则表达式中的任何位置使用,即:'_^' 和 \_$。因此,空行表达式可以写成 \_^\s*\_$ 而不是 \n\s*\n,从而使完整的表达式为:

\v^.*.wpd\_.{-}\_^\s*\_$

这或许更接近回答了楼主为什么无法在表达式中使用行首字符的问题。

太好了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接