在进行字符串替换(^M
)时,Vim处理:s/x/y/
的方式似乎存在某种不对称。
也许一个例子是最好的;说我们有这个文本文件:
foo:bar:biz
我想把它分成几行。这很好用:
:s/:/^M/g
(请注意,^M
是通过输入Ctrl-V
,Enter
生成的。
这导致文本文件:
foo
bar
baz
现在,如果我撤消并再试一次,我注意到不工作:
:s/:/\n/g
此处,生成的文字为:
foo^@bar^@biz
也就是说,它们由ASCII NUL
字节(0x00
)连接。
问题1:为什么在\n
字节的替换结果中使用NUL
?
现在,我认为“好吧,我猜^M
在某种程度上被用作'行分隔符'字符,对于Vim来说;我可以使用它。”
所以我做了另一个实验,从每行一项文本文件开始:
foo
bar
baz
现在,我想用冒号加入它们,所以看起来就像上面的第一个化身。
所以我跑:
:%s/^M/:/
但这失败了,错误:
E486: Pattern not found: ^M
但是,此命令可以正常工作:
:%s/\n/:/
制造
foo:bar:biz:
(我可以自己摆脱尾随冒号)
所以问题2 :为什么\n
在这种情况下有效,^M
没有?
最终,问题3 :为什么\n
和^M
之间存在这种不对称性,具体取决于它是否位于字符串替换的右侧或左侧命令?
答案 0 :(得分:2)
搜索时,\n
是一个"全能"原子,方便地匹配任何类型的"行尾":CRLF
,CR
和LF
。
替换时,\n
为<Nul>
,并表示为^@
。
更换时,\r
是合法的&#34;行尾&#34;对于当前的fileformat
。
简而言之,习惯这种模式并继续:
:s/\n/\r
请参阅:help NL-used-for-Nul
和CR-used-for-NL
。