1. 单次运行
:substitute
命令即可解决问题。我可以看到这种方法的两种略有不同的实现。它们都遵循相同的表达式替换模式:
:%s/"\([^"]*\)"/\='"['.Q.']"'/g
根据上面的命令,用双引号括起来的所有零个或多个字符的序列都将替换为 \=
符号后指定的表达式的评估结果(请参阅 参考资料:help sub-replace-\=
)。与周围的括号和引号连接的是替换表达式 Q
,表示将逗号分隔列表的文本(由模式的(仅)子匹配捕获)转换为相同列表的字符串,其中项目包含在单引号。
表达式的两个版本 Q
如下。
2. 第一个版本很简单:
使用逗号作为分隔符将匹配的文本分解为元素列表:
split(submatch(1), ',', 1)
(最后一个参数在这里是可选的,只有在双引号字段的开头或结尾可能有空元素时才需要。)
用引号括起来:
map(‹…›, '"''".v:val."''"')
并将它们按顺序连接回来,与分隔逗号交替:
join(‹…›, ',')
结合这些步骤,我们得到表达式
join(map(split(submatch(1), ',', 1), '"''".v:val."''"'), ',')
3. 第二个,性能更高一点的表达式 Q
也不是很复杂;它只是一个替换(在替换内部,就像Q
在:s
命令内部一样)。在我们的处置中,我们拥有substitute()
与同名命令等效的功能。
表达方式
substitute(submatch(1), '[^,]\+', "'&'", 'g')
导致所有出现的不包含逗号的非空字符序列被更改为它们本身,并在两端附加单引号。
如果我们希望这个表达式也处理空列表项(就像上面的第一个变体一样),我们需要做的就是将最后一个模式更改为
'\%(^\|,\)\zs[^,]*'
这样,它也允许空序列,但受限于它们位于开头或逗号之后。(查看:help \zs
并:help \%(
更好地理解更改后的模式是如何工作的。)
4. 因此,我们可以使用以下两个命令之一:
:%s/"\([^"]*\)"/\='"['.join(map(split(submatch(1),',',1),'"''".v:val."''"'),',').']"'/g
或者
:%s/"\([^"]*\)"/\='"['.substitute(submatch(1),'\%(^\|,\)\zs[^,]*',"'&'",'g').']"'/g
它们都适用于一行中的所有引用字段。