我正在尝试编写一个匹配任何包含“.wpd”的行的正则表达式,然后匹配之后的所有行,直到它到达一个空行(包括空行)。
这是我尝试过的:
/\v^.*.wpd\_.\{-}^\s*$
\{-}
但是, “所有字符包括换行符”字符类之后的非贪婪运算符\{-}
似乎不起作用。如果我使用
/\v^.*.wpd\_.*
这将匹配包含“.wpd”的下一行,然后是之后的所有行。但是,一旦我将其更改*
为\{-}
,它就根本不匹配任何东西。
我究竟做错了什么?谢谢!
这个似乎有效:
/\v^.*\.wpd\_.{-}\n\s*\n
您不能在^
正则表达式中使用原子(与 相同$
),它仅在前面(后面)有其特殊含义;在其他地方,它被视为文字字符。用于匹配正则表达式中的换行符,如 perreal 的回答所示。\n
(?s)[^\n\r]*\.wpd(.*?)\n{2}
(?s) - 打开“点匹配换行符”以跨行搜索
[^\n\r]* - 从行首开始,匹配任何不是换行符的内容
.wpd - 匹配“.wpd”
(.*?) - 匹配任何东西,非贪婪,包括换行符(因为我们之前打开了 (?s) )
\n{2} - ...直到您连续找到两个换行符,这将是一个空行
:)
以下是对@perreal 上述答案的一大支持评论,以及我自己的答案版本,我觉得它更直观。
让我们根据http://vimdoc.sourceforge.net/htmldoc/pattern.html#/magic剖析下面的正则表达式
/\v^.*\.wpd\_.{-}\n\s*\n
\v
(小写 v):这是“非常神奇”的运算符,表示在它之后的所有 ASCII 字符,除了 '0'-'9'、'a'-'z'、'A'-'Z' 和 ' _'有特殊含义。
因此,像*
, ^
,这样的字符$
在模式中不需要转义,但是为了_
具有特殊含义(例如修改 的行为.
以匹配换行符),它需要进行转义。因此,使用\v
set,您需要\_
后者具有特殊含义。
要真正了解表达式的very magic
简化程度,请将其与相同的表达式进行比较,使用very NOmagic
(uppercase \V
):
/\V\^\.\*.wpd\_\.\{-}\n\s\*\n
(very nomagic) vs
/\v^.*\.wpd\_.{-}\n\s*\n
(very magic)
^.*\.wpd
: 贪婪地匹配任何东西 ( .*
) 从行首 ( ^
) 直到.wpd
\_.
: 匹配单个字符,可以是
任何字符,包括换行符。
请注意,使用\v
set,模式必须如上所述转义下划线。
{-}
*
: 是量词的非贪心等价物。因此,在.*BLAH
BLAH 之前匹配最可能的字符的where 将匹配最不可能的字符.{-}BLAH
。要查看此操作,请查看此(在这种情况下,我不得不使用?
而不是{-}
因为该正则表达式是 PCRE):
\n\s*\n
: 匹配一个可能包含一个或多个空格或制表符的空行
\_.{-}\n\s*\n
: 结合了上述两个,意味着
匹配尽可能少的字符,包括换行符 ( \_.
) 直到空行 ( \n\s*\n
)
\v^.*\.wpd\_.{-}\n\s*\n
:最后把它放在一起,
设置非常神奇的运算符(可能通过不需要转义除了_
特殊含义之外的任何内容来简化模式),搜索包含.wpd
并匹配的任何行,直到最接近的空白行。
唯一的修改是用于表示空行的表达式。我发现根据行首 ('^') 和行尾 ('$') 字符定义空行很有用,但是按原样,它们不能在正则表达式中的任何地方使用,除非分别是开头和结尾。
对于上述用例,有一些变体可以在正则表达式的任何地方使用,即:'_^' 和\_$
分别。因此,空行表达式可以写成\_^\s*\_$
代替\n\s*\n
,从而形成完整的表达式:
\v^.*.wpd\_.{-}\_^\s*\_$
这可能更接近于回答 OP 关于他们为什么无法在表达中使用行首字符的问题。
呸!