对于vim中^$及删除空白的理解

对于vim^$及删除空白的理解

目录

基础... 1

举例... 3

实战演练... 5

1.      删除空行... 5

2.      删除空白行... 6

3.      多个空行合并成一个空行... 7

4.      删除行末空白... 8

 

 

基础

<![if !supportLists]>1.        <![endif]>说明

本文以下图为例,展开说明对删除空白的理解

<![if !vml]><![endif]>

<![if !supportLists]>1.        <![endif]>基础理论一 行理论与串理论

<![if !supportLists]>1)        <![endif]>我们看到的结果是显示的结果,其实际存储时是在每一行结尾处加一个控制字符\n,显示的时候一遇到\n就显示换行。

如下图可以理解为wowo\n\n\nwo\n

<![if !vml]><![endif]>

1

这里的$只是一种显示,表示一行的结尾,并不是实际的内容。在这里要把内容与显示分开理解。显示的时候一遇到\n就换行,并显示一个$

<![if !supportLists]>2)        <![endif]>\n 是一种控制符,如果文件内容出现\n 并不会匹配到

下图是输入 /\n  后的结果<![if !vml]><![endif]>

<![if !supportLists]>3)        <![endif]>看上去的空行  可以理解为 \n  这里的空要理解是一种概念,而不是真正用眼睛看到的空行。

<![if !supportLists]>2.        <![endif]>基础理论二 

<![if !supportLists]>1)        <![endif]>^ $正则理论

^$ 匹配“空” 但不匹配空行后面的回车\n,即我们看到的空行实际上是“空”\n,这里加引号以区别我们看到的空行。或者说^$匹配的是“空”这种概念。[用行理论]

^ 匹配所有行的开头,这里的开头可以理解为位置 用行理论

$匹配所有行的行尾,这里的结尾也可以理解为位置用行理论

^wo  代表一行的开头为wo,并匹配这个字符 用串理论

$wo  wo$(估计以前写错了)代表一行的结尾为wo,并匹配这个字符用串理论

wo^ 无效  ,注意并不等价于wo

$wo 无效 ,注意并不等价于wo

\n ^等价于\n

$\n等价于\n

总结:^ $与字符串联用时用串理论。单个或合用时用行理论

 

<![if !supportLists]>3.        <![endif]>基础理论三 s处理串 g 处理行

<![if !supportLists]>1)        <![endif]>举例:^$同样是匹配空行, g/^$/d  可以将空行删除, 但%s/^$//g却不能删除空行。因为g处理的是行,只要找到有空行的行就删除了s处理的是字符串,虽然匹配到了空行并把空行替换成空,但换行仍在,所以应该写成 %s/^$\n//g

<![if !supportLists]>2)        <![endif]>再比如:\n$  对于g/\n$/d  表示一行的结尾有\n,而所用行的结尾都是\n,所以会删除所有行。对于%s/\n$//g 表示删除连续2\nk 中前面那个\n,所以其效果是删除空行。

<![if !supportLists]>3)        <![endif]>正因为s 处理串 g处理行,所以g只能处理删除操作,而不能处理替换操作。广义来讲删除是另一种替换(替换成空)所以g能处理的s也能处理,但相对麻烦。所以对于行的处理可以考虑用g 对于行中的字符的处理再考虑用s

<![if !supportLists]>4.        <![endif]>最后说明

^ $有时用行理论解释,有时用串理论解释。s命令用串理论解释,g命令用行命令解释。当混合时,只要有用行理论解释的,就用行理论解释。否则用串理论解释。

如:%s/^/1/g  在每一行前加一个1。由于^用行理论解释,所以用行理论解释。

g/^$/d  直接用行理论解释。

 

举例

<![if !supportLists]>1.        <![endif]>%s/$/1/gc 

行尾加一个1,这里把行尾理解成一种位置,而不要理解成一个字符。如下图1是一行中最后一个字符,但不要把1理解成行尾,注意图中的$只是一种显示,要与表达式中的$区别开来
<![if !vml]><![endif]>

2

<![if !supportLists]>2.        <![endif]>%s/^/1/g  会在每行的行首加一个1

<![if !vml]><![endif]> 

 

4

<![if !supportLists]>3.        <![endif]>%s/\n/1/gc    %s/$\n/1/gc    %s/\n^/1/g
把换行替换成1, 也即所有行都一行了。
<![if !vml]><![endif]>

3

<![if !supportLists]>4.        <![endif]>%s/^\n/1/g 

\n的后面还有一个\n  即把\n\n中的第2\n替换成1
<![if !vml]><![endif]>

6

<![if !supportLists]>5.        <![endif]>%s/\n$/1/g 
<![if !vml]><![endif]>

9

\n$ 表示在\n的前面还有一个\n时匹配前面那个字符,所以也就是说把两个连续\n中的前一个替换成1

5 与例6 展示了%s/^\n/1/g  %s/\n$/1/g的区别虽然 %s/^\n//g %s/\n$//g 在删除空行时表现一样。这样更进一步说明了两个\n理论的正确性。

<![if !supportLists]>6.        <![endif]> %s/^$/1/g

仔细看下图,把空行替换成了1, 再次强调要把空行与空行\n区分开来,这里把空行替换成了1,而不是把空行\n替换成了1

<![if !vml]><![endif]>

7

 

实战演练

<![if !supportLists]>1.      <![endif]>删除空行

删除空行,这里的空行是指纯粹的空行,不带空白字符

<![if !supportLists]>1.1.    <![endif]>g/^$/d

g 处理的是行,找到有空行的行,然后删除即达到了删除空行的目的。

g/^$\n/d  也可以。

 

<![if !supportLists]>1.2.    <![endif]>g/^\n/d

匹配以\n开头的行,并删除。即删除空行。

g/\n$/d  会删除所有行,因为所有行都是以\n结尾的。

也再一次证明了g用行理论, s用串理论。

<![if !supportLists]>1.3.    <![endif]>%s/^$\n//g

<![if !vml]><![endif]>

11
解释:^$\n 匹配空行\n 空行\n 替换成空,即达到了删除空行的目的。

另一种解释:其中的表达式$\n 等价于\n  所以^$\n 就变成了^\n  即表示在\n的后面还有一个\n,把后面那个\n替换成空。
可以看出\n 等价于 ^\n  所以上述命令也可以写成 %s\^\n//g

<![if !supportLists]>1.4.    <![endif]>%s/^\n//g

实质就是把连续两个\n中的后面的那个\n替换成空,由于替换成空后剩余的\n又连成了一片,如此下去,直到还剩一个\n

<![if !supportLists]>1.5.  <![endif]>%s/\n$//g

 <![if !vml]><![endif]>

12

只能删除空行,是那种不包括空白的空行

实质就是把连续两个\n中的前面的那个\n替换成空,由于替换成后剩余的\n又连成了一片,如此下去,直到还剩一个\n

 

v/./d  也可以删除空行  (是空行不是空白行)

v命令代表g命令的相反,即g命令如果选择则v命令不选择

.代表非空行。 把v/./d 会删除空行

<![if !supportLists]>2.      <![endif]>删除空白行

<![if !supportLists]>2.1.    <![endif]>%s/^\s*$\n//g

解释:匹配以空白开头,以空白结尾  \n  

由于  $\n \n 等价所以  上式也可写成  %s/^\s*\n//g

<![if !supportLists]>2.2.    <![endif]>%s/^\(\s*\n\)\+//g

该例其实是上一例的变种,只是上一例要替换2次(对于本文档的例子),而本例只替换1次。该方法在把多个空白行变成一个空行是有用

 

         <![if !vml]><![endif]>

14删除后状态

解释 %s/^\(\s*$\n\)\+//g效果一样
+
指的是重复至少一次。+ 号前面的都要重复,即^(\s*\n)  由于()与+号有其特殊的含义,所以用\进行转义。

所以上述表达式的关键就是^(\s*)+ 的理解。即在\n的后面有一些空白,而这些空白的后面有一个\n ,并且这些模式出现了1次以上,即<首行空白>\n 连续1次以上的模式。

举个例子
第一行\n
<
空白字符>\n
<
空白字符>\n
第二非空白行
的内容就是 第一行\n<空白字符>\n<空白字符>\n第二非空白行
对于^(\s*\n)+ 匹配的是<空白字符>\n<空白字符>\n  也就是说^(\s*\n)出现了二次。然后把这个匹配项替换成空。
\s*
表示空白字符出现任意多次(0次或0次以上)至于具体是空格还是tab,还是两者的混合没有关系,都当成抽象的\s即可。即如 <空格><tab>  <tab><tab> <空格><空格> 都是\s*的匹配项。
注意对于%是必须的,%表示查找的范围是全文件,若不加则表示查找当前行,一行之内是不会出现\n的,更不会出现^(\s*)+匹配的情况。所以%是必须要加的。

<![if !supportLists]>2.3.  <![endif]> g/^\s*$/d 

解释一下:g前面不加范围,默认是全文件,所以在全文件中搜索 ^\s*$ 的模式,即删除 含有 空白开头并以空白结尾的 行。

<![if !supportLists]>3.      <![endif]>多个空行合并成一个空行

<![if !supportLists]>3.1.    <![endif]>%s/^\(\s*\n\)\+/\r/g

将多个空行、含有空白字符的空行合并成一个空行。在2.2节里已说过,这里替换一次,所以能将多个空行合并成一个空行。替换一次的原因是从串的角度分析得来。

<![if !supportLists]>3.2.    <![endif]>%s/^\n$//g

解释一下^\n 可以理解为当\n的后面还有一\n时匹配后面的那个\n\n$可以理解为当\n的前面还有一个\n时匹配前面那个\n,所以两个合起来就是当同时满足\n的后面有一个\n\n的前面也有一个\n时匹配中间那个\n也即匹配3个连续\n的中间那个\n,由于把\n替换成了空,所以可以一直替换直到还剩两个\n

<![if !supportLists]>4.      <![endif]>删除行末空白

<![if !supportLists]>4.1.     <![endif]>%s/\s\+$//g.

\n的前面有一个或多个空白,把这些空白替换成空。对于带有空白的空行会删去空白,但空行仍然保留

 

删除行前空白

%s/^\s\+//g

 

 





转载于:https://www.cnblogs.com/mang/archive/2013/02/21/2920249.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值