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

时间:2021-02-02 20:00:51

标签: vim

我有一个包含很多 let string = 'hello I am *bold* text, and I am _italic_, I am ~line-through~ I am *bold again!*'; // html formatter const htmlFormat = [ { symbol: '*', tag: 'b' }, { symbol: '_', tag: 'em' }, { symbol: '~', tag: 'del' }, { symbol: '`', tag: 'code' }, ]; htmlFormat.forEach(({ symbol, tag }) => { if(!string) return; const regex = new RegExp(`\\${symbol}([^${symbol}]*)\\${symbol}`, 'gm'); const match = string.match(regex); if(!match) return; match.forEach(m => { let formatted = m; for(let i=0; i<2; i++){ formatted = formatted.replace(symbol, `<${i > 0 ? '/' : ''}${tag}>`); } string = string.replace(m, formatted); }); }); console.log(string); // hello I am <b>bold</b> text, and I am <em>italic</em>, I am <del>line-through</del> I am <b>bold again!</b> 的数据文件(逗号分隔)(它是由 R 生成的)。我在 vim 中打开文件并尝试将所有 NA 值替换为空字符串。

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

NA

一旦我完成了搜索替换,预期的输出应该是:

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

换句话说,除了单词 {​​{1}}、1,1,,,,NATIONAL,,1,NANA,1,AMERICANA,1 NA 之外的所有 NATIONAL 都应该被替换。

我在 vim 中使用了以下命令来做到这一点:

NANA

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

AMERICANA

如您所见,替换过程中遗漏了一个 1, $ s/\,NA\,/\,\,/g

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

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

2 个答案:

答案 0 :(得分:2)

  1. , 没有特殊含义,因此您不必对其进行转义:

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

    这不能解决您的问题。

  2. 您可以使用 % 作为 1,$ 的简写:

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

    这也不能解决您的问题。

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

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

    这仍然不能解决您的问题。

  4. 这使得那些逗号,您曾经将匹配限制为 NA 并且导致错误,无用:

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

参见 :help :range:help \<

答案 1 :(得分:1)

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

TL;DR:NAME