我想转换双引号中的全逗号分隔字符串文字,如下所示:
"hello,world,stack,overflow"
Cassandra列表格式:
"['hello','world','stack','overflow']"
其中每个元素都包含在单引号中,整个原始字符串包含在方括号和双引号中。如何在Vim中实现?
在我的输入中,这种用逗号分隔的引用字符串是CSV格式的表中的行的一部分。下面是一个例子:
other,fields,123,456,"hello,world,stack,overflow"
second,row,567,890,"another,comma,separated,string"
...
我想把它转换成:
other,fields,123,456,"['hello','world','stack','overflow']"
second,row,567,890,"['another','comma','separated','string']"
...
我的目标字符串没有一个跨多行。
2条答案
按热度按时间ibrsph3r1#
试试这个
或者一下子全部
这在示例中起作用。如果行中有多对引号,则此操作将不起作用。
说明
这将查找前后都有引号的字符串,并使用lookaheads和lookbehinds。然后,我们捕获所有不是逗号或引号的内容,并将其替换为单引号中的捕获部分。这将抛出任何前导或尾随空格。
如果您以前使用过
:s
,那么这应该是不言自明的它使用负向前查找查找第一个后面没有左括号的引号,并将其替换为右括号和引号。
在考虑了这一点多一点,我认为你可以做整个文件在一个镜头,无论天气有一个以上的报价对行。
第一个函数只是一个辅助函数,它使替换命令更容易输入。(你可以在一行中执行三个替代命令,但那会很难看)。它和上面的东西做同样的事情。
第二个函数找到所有带引号的字符串,并将其传递给函数,然后立即替换所有字符串。你知道哪一个是开始和结束引号,因为保证只有一对引号。
之所以这样做并且正则表达式解析器不会感到困惑,是因为模式匹配在第一个匹配结束之后开始。如果你有字符串
" A " B " C "
" A "
将是第一个匹配," C "
将是第二个匹配,因为当解析器试图在B之后进行匹配时,它会看到B " C "
,而这并不匹配。要在你的vim中运行这个,只需将这两个函数复制到你的vimrc中。在你想要运行的文件中运行下面的命令。
cbeh67ev2#
**1.**很有可能一次运行
:substitute
命令就能解决问题。我可以看到这种方法的两种稍微不同的实现。它们都遵循相同的表达式替换模式:根据上面的命令,所有包含零个或多个字符的双引号序列都将被
\=
符号后指定的表达式的计算结果替换(参见:help sub-replace-\=
)。要与周围的方括号和引号连接的是替换表达式Q
,它代表一个表达式,该表达式将逗号分隔的列表(由模式的(唯一)子匹配捕获)的文本转换为同一列表的字符串,其中项目用单引号括起来。表达式
Q
的两个版本如下所示。**2.**第一个版本很简单:
1.使用逗号作为分隔符将匹配的文本分解为元素列表:
(The最后一个参数在这里是可选的,只有当双引号字段的开头或结尾可能有空元素时才是必需的。)
1.用引号包围它们:
1.然后将它们按顺序连接起来,用逗号分隔:
结合这些步骤,我们得到表达式
**3.**表达式
Q
的第二个更高性能的版本并不复杂;它只是一个替换(在替换内部,如Q
在:s
命令内部)。我们可以使用substitute()
函数,它的功能相当于同名命令。表达
导致所有不包含逗号的非空字符序列的出现,被更改为两端附加单引号的自身。
如果我们希望这个表达式也处理空列表项(就像上面的第一个变体一样),我们需要做的就是将最后一个模式改为
这样,它也允许空序列,但限制它们在最开始或逗号之后。(请参阅
:help \zs
和:help \%(
,以更好地了解更改后的模式如何工作。**4.**因此,我们可以使用以下两个命令之一:
或
它们都适用于一行中所有带引号的字段。