\n和\ r在Vim中不同情况下的不同行为

fuj*_*471 8 vim

假设我有一个只有一个角色'的线,让我们看看\n在不同情况下的效果:

:s/s/a\nb
a^@b
:s/s/a\\nb
a\nb
:s/s/a\\\nb
a\^@b
:s/s/a\\\\nb
a\\nb

:echo "a\nb"
a
b
:echo "a\\nb"
a\nb
:echo "a\\\nb"
a\
b
:echo "a\\\\nb"
a\\nb
Run Code Online (Sandbox Code Playgroud)

那么为什么\n表现不一样呢?然后让我们看看使用条件substitute()

:echo substitute(" ", " ", "a\nb", "")
a
b
:echo substitute(" ", " ", "a\\nb", "")
a
b
:echo substitute(" ", " ", "a\\\nb", "")
a
b
:echo substitute(" ", " ", "a\\\\nb", "")
a\nb
Run Code Online (Sandbox Code Playgroud)

这一次,\n仍被解释为"换行",但如何解释反斜杠?

下一部分,说我还有一个只有一个角色的',而不是\n,\r将要研究:

:s/s/a\rb
a
b
:s/s/a\\rb
a\rb
:s/s/a\\\rb
a\
b
:s/s/a\\\\rb
a\\rb
Run Code Online (Sandbox Code Playgroud)

\r的效果是一样\n:echo "a\nb",和反斜线的规则是一样的.

:echo "a\rb"
b
:echo "a\\rb"
a\rb
:echo "a\\\rb"
b\  "This is the most strange case!!!
:echo "a\\\\rb"
a\\rb
Run Code Online (Sandbox Code Playgroud)

\r在这种情况下做什么?而第三个子案甚至更奇怪.

:echo substitute(" ", " ", "a\rb", "")
b
:echo substitute(" ", " ", "a\\rb", "")
b
:echo substitute(" ", " ", "a\\\rb", "")
b
:echo substitute(" ", " ", "a\\\\rb", "")
a\rb
Run Code Online (Sandbox Code Playgroud)

不过,我无法理解不同数量的反斜杠是如何表现的.

我的问题是:

  1. 为什么\n还是\r不同的表现下:substitute,echo直接substitute()
  2. 使用时如何解释不同数量的反斜杠效果substitute()
  3. Vim \n\rVim 之间有什么区别?

补充1:

如果我:let s = "a\\\nb"然后<C-r>=s在缓冲区中看到它,我明白了

a\
        b
Run Code Online (Sandbox Code Playgroud)

怎么解释这个?

FDi*_*off 2

  1. 对于 和:echosubstitute()\n换行符并且\r是回车符。他们应该做你所期望的事情。\n将光标移动到下一行(第 1 列),并将\r光标移动到同一行的第 1 列。对于\r打印的下一个字符将覆盖先前打印的字符。(我主要关注下面的substitute()和):echo:substitute

  2. 为什么 echo 和 Replace() 的行为不同。您需要了解该字符串发生了多少种解释。对于 echo 只发生一种情况,对于 replacement() 则发生两种情况。

    :echo substitute(" ", " ", "a\\\rb", "")
    b
    :echo substitute(" ", " ", 'a\\\rb', "")
    b\
    
    Run Code Online (Sandbox Code Playgroud)

第二个与您对 echo 的期望相同。双引号中的字符串的内容根据 进行了更改:help expr-quote。这意味着如果字符串仅被解释一次(使用单引号),那么 echo 和 Replace 都会看到相同的内容

"a\\\rb"被解释为a\rb在一种解释之后,然后a<CR>b在第二种解释之后。这导致只能b打印。

  1. \r\n根据它们的使用地点而变化。唯一的区别是在替换中用作换行符的:substitute位置。\r

:substitute这是和substitute()表现不同的情况之一,

:substitue如下

  <CR>        split line in two at this point
              (Type the <CR> as CTRL-V <Enter>)                  s<CR>
  \r          idem                                               s/\r
  ...
  \n          insert a <NL> (<NUL> in the file)
              (does NOT break the line)                          s/\n
Run Code Online (Sandbox Code Playgroud)

<NUL>与which相同,^@与换行符不同)

substitute()接下来

The special meaning is also used inside the third argument {sub} of
the substitute() function with the following exceptions:
...
  - <CR> and \r inserts a carriage-return (CTRL-M).
...
Run Code Online (Sandbox Code Playgroud)

  • @fujianjin6471实际上,如果您启用了某种自动缩进功能,则可能会发生这种情况,因为表达式寄存器添加的字符就像手动键入的一样(我认为)。看看您是否有某种文件类型,它可能带有一个可以执行此操作的 indentexpr,或者您可能打开了一些其他设置。 (2认同)