Why is \r a newline for Vim?
Asked Answered
I

5

286

From question How to replace a character for a newline in Vim?. You have to use \r when replacing text for a newline, like this

:%s/%/\r/g

But when replacing end of lines and newlines for a character, you can do it like:

:%s/\n/%/g 

What section of the manual documents these behaviors, and what's the reasoning behind them?

Isolated answered 16/9, 2008 at 11:34 Comment(3)
What is the % for when searching and replacing?Hexangular
@qed: by default :s will only apply the substitution to the current line. :%s makes it address the whole file. More.Burnaby
+c24w I think he is referring to the '%' between the slashes, the first example the '%' being in the search location, and in the replace location in the second example, but @Hexangular to answer your question, those '%'s are matched literally.Cornelia
R
157

From vim docs on patterns:

\r matches <CR>

\n matches an end-of-line - When matching in a string instead of buffer text a literal newline character is matched.

Ragnar answered 16/9, 2008 at 15:16 Comment(3)
For me the point of confusion is that \r and \n mean different things when used is the search pattern and the replacement pattern.Panthia
@Panthia Yup! See my answer :)Janes
The question in the title is "why" and this is not answeredRattle
J
239

From http://vim.wikia.com/wiki/Search_and_replace :

When Searching

...

\n is newline, \r is CR (carriage return = Ctrl-M = ^M)

When Replacing

...

\r is newline, \n is a null byte (0x00).

Janes answered 12/9, 2012 at 13:2 Comment(5)
This answer helped me the most. Also, for more information, :h :s%, especially the last paragraph. (via :h :s)Naturally
i wrote about that in even more depth - https://mcmap.net/q/40514/-how-to-replace-a-character-by-a-newline-in-vimOutdare
Yes, you wrote more, but I don't think you added anything material.Janes
but WHY........Rattle
@Rattle Excellent question. I have no idea (even 13 years later). It's just one more "grey-beard" thing we have to memorize to make ourselves into the GNU/Linux sages we revere. :sigh:Janes
R
157

From vim docs on patterns:

\r matches <CR>

\n matches an end-of-line - When matching in a string instead of buffer text a literal newline character is matched.

Ragnar answered 16/9, 2008 at 15:16 Comment(3)
For me the point of confusion is that \r and \n mean different things when used is the search pattern and the replacement pattern.Panthia
@Panthia Yup! See my answer :)Janes
The question in the title is "why" and this is not answeredRattle
S
143

Another aspect to this is that \0, which is traditionally NULL, is taken in s//\0/ to mean "the whole matched pattern". (Which, by the way, is redundant with, and longer than, &).

  • So you can't use \0 to mean NULL, so you use \n
  • So you can't use \n to mean \n, so you use \r.
  • So you can't use \r to mean \r, but I don't know who would want to add that char on purpose.

—☈

Sihon answered 12/9, 2012 at 13:54 Comment(4)
Good point! So this is a hack around \0 - backreference to 0-th nested group - whole regexp. This is a very good answer, but it makes me dissapointed, that I can't use \r in replacement... (meaning: insert #(13), for example in a "normal" file (== unix EOLs).Mikimikihisa
OK, the answer is in the Vim docs. Just escape \^M or \<CR>, with a normal backslash. Nice. ----- <CR> split line in two at this point (Type the <CR> as CTRL-V <Enter>) s<CR> \r idem -------- s/\r \<CR> insert a carriage-return (CTRL-M) (Type the <CR> as CTRL-V <Enter>) s/\<CR>Mikimikihisa
"Another aspect"? You're too modest! Explaining precisely_why_ this happens makes for a superior answer to all the ones just saying how to work around it. +1Piper
This is honestly really great insight into why \n has different meanings in search and replace patterns. Fantastic answer.Lashoh
E
51

:help NL-used-for-Nul

Technical detail:

<Nul> characters in the file are stored as <NL> in memory. In the display they are shown as "^@". The translation is done when reading and writing files. To match a <Nul> with a search pattern you can just enter CTRL-@ or "CTRL-V 000". This is probably just what you expect. Internally the character is replaced with a <NL> in the search pattern. What is unusual is that typing CTRL-V CTRL-J also inserts a <NL>, thus also searches for a <Nul> in the file. {Vi cannot handle <Nul> characters in the file at all}


Endgame answered 16/9, 2008 at 11:57 Comment(0)
U
12

First of all, open :h :s to see the section "4.2 Substitute" of documentation on "Change". Here's what the command accepts:

:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]

Notice the description about pattern and string

For the {pattern} see |pattern|.
{string} can be a literal string, or something
special; see |sub-replace-special|.

So now you know that the search pattern and replacement patterns follow different rules. If you follow the link to |pattern|, it takes you to the section that explains the whole regexp patterns used in Vim.

Meanwhile, |sub-replace-special| takes you to the subsection of "4.2 Substitute", which contains the patterns for substitution, among which is \r for line break/split.

(The shortcut to this part of manual is :h :s%)

Undermanned answered 10/12, 2013 at 10:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.