【问题标题】:Vim RegEx: Match until blank lineVim RegEx:匹配直到空行
【发布时间】:2012-09-04 19:39:22
【问题描述】:

我正在尝试编写一个正则表达式,它将匹配任何包含“.wpd”的行,然后匹配之后的所有行,直到它到达一个空行(包括空行)。

这是我尝试过的:

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

但是,“所有字符包括换行符”字符类\{-} 之后的非贪婪运算符\{-} 似乎不起作用。如果我使用

/\v^.*.wpd\_.*

这将匹配包含“.wpd”的下一行,然后是 all 行。但是,一旦我将* 更改为\{-},它就根本不匹配任何东西。

我做错了什么?谢谢!

【问题讨论】:

  • 在下面查看我的答案。您非常接近,只需要使用行首和行尾字符的anwhere 变体。

标签: regex vim newline


【解决方案1】:

这个似乎有效:

/\v^.*\.wpd\_.{-}\n\s*\n

【讨论】:

  • 太棒了,谢谢。我接受了 Ingo 的回答,因为他解释了为什么我的回答不起作用,但这是一个艰难的决定,我很感激你的回答。
【解决方案2】:

你不能使用原子^$也一样)inside正则表达式,它只有在前面(后面)有它的特殊含义;在其他地方,它被视为文字字符。使用 \n 匹配正则表达式中的换行符,如 perreal 的回答所示。

【讨论】:

  • 或者,使用锚点的 anywhere 等效项。因此,请使用\_^\_$。因此表达式可以简化为\v^.*.wpd\_.{-}\_^\s*\_$
【解决方案3】:
(?s)[^\n\r]*\.wpd(.*?)\n{2}

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

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

.wpd - 匹配“.wpd”

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

\n{2} - ...直到您连续找到两个换行符,这将是一个空行

:)

【讨论】:

    【解决方案4】:

    以下是对@perreal 上述答案的大量支持性评论,以及我自己对该答案的版本,我觉得它更直观。

    让我们根据http://vimdoc.sourceforge.net/htmldoc/pattern.html#/magic来剖析下面的正则表达式

    /\v^.*\.wpd\_.{-}\n\s*\n
    
    1. \v(小写 v):这是“非常神奇”的运算符 表示在它之后的所有 ASCII 字符的模式中,除了 '0'-'9'、'a'-'z'、'A'-'Z' 和 '_' 具有特殊含义。

      因此,*^$ 在模式中不需要转义,但_ 有特殊含义(如修改. 的行为以匹配换行符),需要转义。因此,使用\v 设置,您需要\_ 以使后者具有特殊含义。
      要真正了解very magic 简化了多少表达式,请将其与使用very NOmagic(大写\V)的相同表达式进行比较:

      /\V\^\.\*.wpd\_\.\{-}\n\s\*\n(非常游手好闲)vs
      /\v^.*\.wpd\_.{-}\n\s*\n(很神奇)

    2. ^.*\.wpd:贪婪匹配从行首 (^) 到 .wpd 的任何内容 (.*)

    3. \_. :匹配单个字符,可以是 任何字符,包括换行符。
      请注意,设置\v 后,该模式必须已转义下划线,如上所述。

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



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

    6. \_.{-}\n\s*\n:结合以上两个,意思是
      匹配尽可能少的字符,包括换行符(\_.)直到空行(\n\s*\n

    7. \v^.*\.wpd\_.{-}\n\s*\n:最后把它放在一起,
      设置 very magic 运算符(可能是为了简化模式,除了 _ 之外不需要转义特殊符号含义),搜索任何包含.wpd 的行并匹配到最接近的空行。


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

    唯一的修改是用于表示空行的表达式。我发现根据行首 ('^') 和行尾 ('$') 字符定义空行很有用,但是按原样,它们不能在正则表达式中的任何地方使用,除非分别是开头和结尾。

    对于上述用例,有一些变体可以在正则表达式的任何地方使用,即:分别为:'_^' 和 \_$。因此空行表达式可以写成\_^\s*\_$而不是\n\s*\n,这样就形成了完整的表达式:

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

    这也许更接近于回答 OP 关于他们为什么无法在表达式中使用行首字符的问题。

    呼!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-22
      • 2012-06-27
      相关资源
      最近更新 更多