^M vs \n in vim 字符串替换
^M vs \n in vim string replacement
在进行字符串替换 (:s/x/y/
) 时,Vim 对待 ^M
的方式似乎存在某种不对称性。
也许举个例子最好;假设我们有这个文本文件:
foo:bar:biz
我想把它分成几行。这很好用:
:s/:/^M/g
(注意 ^M
是通过键入 Ctrl-V
、Enter
产生的)
文本文件中的结果:
foo
bar
baz
现在,如果我撤消它并重试,我注意到这不有效:
:s/:/\n/g
这里,生成的文本是:
foo^@bar^@biz
也就是说,它们是由ASCIINUL
字节(0x00
)连接起来的。
问题1:为什么在替换中使用\n
会导致NUL
字节?
现在,我估计 "okay, I guess ^M
is used as the 'line separator' character in some way, for Vim; I can work with that"。
所以我做了另一个实验,从每行一个项目的文本文件开始:
foo
bar
baz
现在,我想用冒号加入它们,所以它看起来像上面的第一个化身。
所以我运行:
:%s/^M/:/
但这失败了,错误是:
E486: Pattern not found: ^M
但是,这个命令确实有效:
:%s/\n/:/
生产:
foo:bar:biz:
(我可以自己去掉尾随的冒号)
那么问题 2:为什么 \n
在这种情况下有效,而 ^M
却无效?
最终,问题 3:为什么 \n
和 ^M
之间存在这种不对称,具体取决于它是在右手还是左手字符串替换命令的一侧?
搜索时,\n
是一个 "catch-all" 原子,可以方便地匹配任何一种 "end-of-line":CRLF
、CR
和 LF
.
替换时,\n
为<Nul>
,表示为^@
。
替换时,\r
是当前fileformat
的合法"end-of-line"。
总之,习惯这种模式,然后继续:
:s/\n/\r
参见 :help NL-used-for-Nul
和 CR-used-for-NL
。
在进行字符串替换 (:s/x/y/
) 时,Vim 对待 ^M
的方式似乎存在某种不对称性。
也许举个例子最好;假设我们有这个文本文件:
foo:bar:biz
我想把它分成几行。这很好用:
:s/:/^M/g
(注意 ^M
是通过键入 Ctrl-V
、Enter
产生的)
文本文件中的结果:
foo
bar
baz
现在,如果我撤消它并重试,我注意到这不有效:
:s/:/\n/g
这里,生成的文本是:
foo^@bar^@biz
也就是说,它们是由ASCIINUL
字节(0x00
)连接起来的。
问题1:为什么在替换中使用\n
会导致NUL
字节?
现在,我估计 "okay, I guess ^M
is used as the 'line separator' character in some way, for Vim; I can work with that"。
所以我做了另一个实验,从每行一个项目的文本文件开始:
foo
bar
baz
现在,我想用冒号加入它们,所以它看起来像上面的第一个化身。
所以我运行:
:%s/^M/:/
但这失败了,错误是:
E486: Pattern not found: ^M
但是,这个命令确实有效:
:%s/\n/:/
生产:
foo:bar:biz:
(我可以自己去掉尾随的冒号)
那么问题 2:为什么 \n
在这种情况下有效,而 ^M
却无效?
最终,问题 3:为什么 \n
和 ^M
之间存在这种不对称,具体取决于它是在右手还是左手字符串替换命令的一侧?
搜索时,\n
是一个 "catch-all" 原子,可以方便地匹配任何一种 "end-of-line":CRLF
、CR
和 LF
.
替换时,\n
为<Nul>
,表示为^@
。
替换时,\r
是当前fileformat
的合法"end-of-line"。
总之,习惯这种模式,然后继续:
:s/\n/\r
参见 :help NL-used-for-Nul
和 CR-used-for-NL
。