vim的 \n 和 \r 什么区别
在vim里,要替换换行符需要查找 \n 但是要替换为换行符则是 \r
也就是说
:s/\n/\r/
什么都不发生。理论上这样我就已经把所有的\n替换为\r了,然后再次查找的时候
/\r
还是啥都没,只有
/\n
有值,求原理~~~
Answers
我之前写过一篇笔记,没有公开,这里放出来供参考。
(原文是 markdown 格式,SF 并不完全支持,不过不影响阅读)
笔记正文
Vim 中换行符的问题
===============
在 Vim 中如果要使用
s/\n/\n/g
会导致文件的换行全部被替换成
^@
字符,按照通常的理解,
s/\n/\n/g
不应该有任何的效果,但在 Vim 中,
\n
的处理略有不同。
[<Nul>
]( http://vimdoc.sourceforge.net/htmldoc... ) characters in the file are stored as [<NL>
]( http://vimdoc.sourceforge.net/htmldoc... ) in memory. In the display they are shown as "^@
". The translation is done when reading and writing files. To match a [<Nul>
]( http://vimdoc.sourceforge.net/htmldoc... ) with a search pattern you can just enter [CTRL-@]( http://www.vim.org/htmldoc/insert.htm... ) or "[CTRL-V]( http://www.vim.org/htmldoc/insert.htm... ) 000". This is probably just what you expect. Internally the character is replaced with a [<NL>
]( http://vimdoc.sourceforge.net/htmldoc... ) in the search pattern. What is unusual is that typing [CTRL-V]( http://www.vim.org/htmldoc/insert.htm... ) [CTRL-J]( http://www.vim.org/htmldoc/insert.htm... ) also inserts a [<NL>
]( http://vimdoc.sourceforge.net/htmldoc... ), thus also searches for a [<Nul>
]( http://vimdoc.sourceforge.net/htmldoc... ) in the file. {Vi cannot handle [<Nul>
]( http://vimdoc.sourceforge.net/htmldoc... ) characters in the file at all}
从这段说明可以了解到在 Vim 中,空字符
<Nul>
(ASCII 0)在内存中是作为
<NL>
(newline) 进行处理的。
\n matches an end-of-line
When matching in a string instead of buffer text a literal newline character is matched.
'\n' 在搜索表达式中是在匹配一个字符串,所以字面意义的 'new line' 字符串会被匹配到,而不是
<Nul>
字符。在替换表达式中 '\n' 会被解释为
<NL>
,于是在内部,
<Nul>
会被输入,所以在替换的表达式中 '\n' 不再表示 'new line' 或者 'end-of-line'。同样,在搜索表达式中,输入 "CTRL-@" 或者 "CTRL-V 000" 表示
<Nul>
字符,但是在内部,他们还是都被替换为
<NL>
进行处理的,这也就是为什么直接键入 CTRL-V CTRL-J(输入的是
<NL>
字符本身)也有相同的效果的原因。
我想之所以会出现有点混乱的原因可能时 Vi 并不支持
<Nul>
字符,而 Vim 由 Vi 发展而来,作者可能为了方便,直接使用了
<NL>
用来表示
<Nul>
,这也就是 'NL-used-for-Nul' 的字面意思。与此同时,
<NL>
原本的作用则使用
<CR>
来替代,这也就是 'CR-used-for-NL' 的字面意思。
When 'fileformat' is "mac", <NL> characters in the file are stored as <CR> characters internally. In the text they are shown as "^J". Otherwise this works similar to the usage of <NL> for a <Nul>.
When working with expression evaluation, a <NL> character in the pattern matches a <NL> in the string. The use of "\n" (backslash n) to match a <NL> doesn't work there, it only works to match text in the buffer.
那么,我们如何在替换表达式里表示
<NL>
呢?答案就是
<CR>
,可以使用 CRTL-V CRTL-M(输入的是
<CR>
字符本身) 或者 '\r',Vim 并不会在文件中直接输入
<CR>
字符,它会根据当前 ‘fileformat’ 的设置来决定使用
<CR>
(Mac),
<NL>
(\*nix) 还是
<CR><NL>
(dos)。
参考资料
--------
- [Vim: \n vs. \r]( http://stackoverflow.com/questions/35... )
- [Why is \r a newline for Vim?]( http://stackoverflow.com/questions/71... )
- [Vim 使用 regex 將 "," 取代成換行]( http://blog.longwin.com.tw/2008/08/vi... )
- [How to replace a character for a newline in Vim?]( http://stackoverflow.com/questions/71... )