关于Vim删除首个PATTERN前内容的命令行为疑问
Vim命令行为解析:删除开头到第一个PATTERN前的内容
原始文件内容
Something from the beginning of a file until my target PATTERN then the content continue until the appearance of other PATTERN in another lines
需求:删除文件开头到第一个PATTERN之前的所有内容(包括首行空行、"Something from"直到"my target"部分),光标位于首行空行的第一个字符。
以下是对每条命令行为的拆解:
1. 命令 :/\_.\{-}PATTERN/d
这条命令的作用是定位到第一个匹配\_.\{-}PATTERN的行,然后删除该行。
\_.匹配任意字符(含换行),\{-}是非贪婪匹配,但:/pattern/d的逻辑是找到匹配pattern的行,只删除该行本身。这里匹配的跨行内容从首行空行开始到PATTERN,但匹配结束的行是第二行("Something from"),所以最终只删除了第二行。
2. 命令 :1,/\_.\{-}PATTERN/d
该命令是删除从第1行到第一个匹配\_.\{-}PATTERN的行之间的所有行。
1,/pattern/的范围是从首行到第一个匹配pattern的行。这里\_.\{-}PATTERN的匹配结束行是第二行,所以范围覆盖第1、2行,最终这两行被删除。
3. 命令 :1,/PATTERN/s/\_.\{-}PATTERN/
这条命令的问题出在范围与跨行匹配的冲突:
1,/PATTERN/的范围是从首行到第一个PATTERN所在的第5行。而\_.\{-}PATTERN是跨行匹配,会忽略行边界从开头一直找最近的PATTERN,但由于Vim在范围执行替换时,跨行匹配会直接覆盖整个范围甚至超出(非贪婪匹配在跨行场景下没有正确停止在第一个PATTERN),最终导致删除了从开头到第二个PATTERN的所有内容。
4. 命令 :1,/PATTERN/s/\_.\{-}PATTERN/PATTERN
和第3条逻辑一致,只是把匹配内容替换成PATTERN:
- 由于匹配到了开头到第二个
PATTERN的内容,替换后加上原本的第二个PATTERN,就出现了PATTERNPATTERN的重复结果。
5. 命令 :1,/PATTERN/-1s/\_.\{-}PATTERN/
这是正确解决方案,原因如下:
1,/PATTERN/-1把范围限制在首行到第一个PATTERN所在行的上一行(也就是第4行),确保范围完全在PATTERN之前。此时用\_.\{-}PATTERN跨行匹配开头到PATTERN前的所有内容,替换为空后,正好保留了PATTERN及后续内容,完全符合需求。
内容的提问来源于stack exchange,提问作者Oliver Leung
相关产品推荐
相关产品推荐

