我有一个包含很多 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,
。
答案 0 :(得分:2)
,
没有特殊含义,因此您不必对其进行转义:
:1,$s/,NA,/,,/g
这不能解决您的问题。
您可以使用 %
作为 1,$
的简写:
:%s/,NA,/,,/g
这也不能解决您的问题。
匹配所有这些 NA
词以排除包含 NA
的其他词的最佳方法是使用词边界:
:%s/,\<NA\>,/,,/g
这仍然不能解决您的问题。
这使得那些逗号,您曾经将匹配限制为 NA
并且导致错误,无用:
:%s/\<NA\>//g
参见 :help :range
和 :help \<
。
答案 1 :(得分:1)
%
而不是 1,$
(%
表示“缓冲区”,也就是整个文件)。\,
。 ,
工作正常。,NA,NA,NA,
中它只能找到第一个 ,NA,
和第三个 ,NA,
,因为中间的 ,
没有自己单独的周围 \zs
。我们可以使用 \ze
(开始)和 NA
(结束)修改匹配以不包含正则表达式的某些字符。这些修改我们的正则表达式以查找被其他字符包围的匹配项,但我们的匹配项实际上并不包含它们,因此我们可以匹配 ,NA,NA,NA,
中的所有 %s/,\zsNA\ze,//g
。TL;DR:NAME