vim 搜索替换应在以下搜索中使用替换文本

vim Search Replace should use replaced text in following searches

我有一个数据文件(逗号分隔),其中有很多 NA(它是由 R 生成的)。我在 vim 中打开文件并尝试将所有 NA 值替换为空字符串。

这是文件中记录的精简版本示例:

1,1,NA,NA,NA,NATIONAL,NA,1,NANA,1,AMERICANA,1

完成搜索替换后,预期输出应该是:

1,1,,,,NATIONAL,,1,NANA,1,AMERICANA,1

换句话说,除了 NATIONALNANAAMERICANA.

之外的所有 NA 都应该被替换

我在 vim 中使用了以下命令来执行此操作:

1, $ s/\,NA\,/\,\,/g

但是,它似乎不起作用。这是我得到的输出:

1,1,,NA,,NATIONAL,,1,NANA,1,AMERICANA,1

如您所见,替换过程中遗漏了一个 ,NA,

有没有人有好的办法解决?谢谢。

一个简单的解决方案是再次 运行 相同的命令,它将处理剩余的 ,NA,。但是,这不是一个可行的解决方案,因为我的实际数据文件有 100 多列和 500K+ 行,每行都有可变数量的 NAs.

  1. 使用 % 而不是 1,$% 表示“缓冲区”,也就是整个文件)。
  2. 您不需要 \,, 工作正常。
  3. Vim 查找离散的、不重叠的匹配项。所以在 ,NA,NA,NA, 它只找到第一个 ,NA, 和第三个 ,NA, 因为中间的 , 没有自己独立的周围。我们可以修改匹配以不包括我们的正则表达式的某些字符 \zs (开始)和 \ze (结束)。这些修改我们的正则表达式以查找被其他字符包围的匹配项,但我们的匹配项实际上并不包含它们,因此我们可以匹配 ,NA,NA,NA,.
  4. 中的所有 NA

TL;DR: %s/,\zsNA\ze,//g

  1. ,没有特殊意义所以不用转义:

    :1,$s/,NA,/,,/g
    

    这不能解决您的问题。

  2. 您可以将 % 用作 1,$ 的 shorthand:

    :%s/,NA,/,,/g
    

    这也不能解决您的问题。

  3. 匹配所有这些 NA 单词以排除包含 NA 的其他单词的最佳方法是使用单词边界:

    :%s/,\<NA\>,/,,/g
    

    还是没有解决你的问题。

  4. 这使得那些您用来将匹配限制为 NA 并导致错误的逗号变得无用:

    :%s/\<NA\>//g
    

参见 :help :range:help \<