首页  >  问答  >  正文

正则表达式 - vim的 \n 和 \r 什么区别

在vim里,要替换换行符需要查找 n 但是要替换为换行符则是 r
也就是说

:s/\n/\r/

什么都不发生。理论上这样我就已经把所有的n替换为r了,然后再次查找的时候

/\r

还是啥都没,只有

/\n

有值,求原理~~~

高洛峰高洛峰2712 天前853

全部回复(1)我来回复

  • 我想大声告诉你

    我想大声告诉你2017-05-16 16:44:44

    我之前写过一篇笔记,没有公开,这里放出来供参考。

    (原文是 markdown 格式,SF 并不完全支持,不过不影响阅读)

    笔记正文

    Vim 中换行符的问题
    ===============

    在 Vim 中如果要使用 s/n/n/g 会导致文件的换行全部被替换成 ^@ 字符,按照通常的理解,s/n/n/g 不应该有任何的效果,但在 Vim 中,n 的处理略有不同。

    :help NL-used-for-Nul

    [<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' 的字面意思。

    :help 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)。

    参考资料
    --------

    1. [Vim: n vs. r](http://stackoverflow.com/questions/35...)
    2. [Why is r a newline for Vim?](http://stackoverflow.com/questions/71...)
    3. [Vim 使用 regex 将 "," 取代成换行](http://blog.longwin.com.tw/2008/08/vi...)
    4. [How to replace a character for a newline in Vim?](http://stackoverflow.com/questions/71...)

    回复
    0
  • 取消回复