Regex 如何在Vim中将逗号分隔的字符串转换为Cassandra列表格式?
我想转换双引号中的全逗号分隔字符串文字,例如:Regex 如何在Vim中将逗号分隔的字符串转换为Cassandra列表格式?,regex,list,vim,replace,cassandra,Regex,List,Vim,Replace,Cassandra,我想转换双引号中的全逗号分隔字符串文字,例如: “你好,世界,堆栈,溢出” 进入: “['hello'、'world'、'stack'、'overflow'” 其中每个元素用单引号括起来,整个原始字符串用方括号和双引号括起来。我如何在Vim中完成它 在我的输入中,这种带引号的逗号分隔字符串是CSV格式表中行的一部分。以下是一个例子: other,fields,123456,“你好,世界,堆栈,溢出” 第二行,567890,“另一个,逗号,分隔,字符串” ... 我想将其转换为: other
“你好,世界,堆栈,溢出”
进入:
“['hello'、'world'、'stack'、'overflow'”
其中每个元素用单引号括起来,整个原始字符串用方括号和双引号括起来。我如何在Vim中完成它
在我的输入中,这种带引号的逗号分隔字符串是CSV格式表中行的一部分。以下是一个例子:
other,fields,123456,“你好,世界,堆栈,溢出”
第二行,567890,“另一个,逗号,分隔,字符串”
...
我想将其转换为:
other,字段,123456,“['hello','world','stack','overflow']”
第二行,567890,“[‘其他’、‘逗号’、‘分隔’、‘字符串’]”
...
我的目标字符串都不跨多行。试试这个
:%s/\v(“.*)@1.很有可能在一次运行
:替换
命令。我可以看到两种稍微不同的实现
两者都遵循相同的替代模式
用一句话:
:%s/“\([^”]*\)“/\=”['.Q.]”/g
根据上面的命令,所有零个或多个字符的序列
包含在双引号中的将替换为
在\=
符号后指定的表达式(请参见:help sub replace-\=
)。
与周围的方括号和引号连接的是
替换表达式Q
表示表达式转换
由的(唯一)子匹配捕获的逗号分隔列表的文本
将模式转换为同一列表的字符串,其中的项包含在
单引号
表达式Q
的两个版本如下所示
2.第一个版本很简单:
使用逗号将匹配的文本分解为元素列表
作为分隔符:
split(子匹配(1),,,,1)
(最后一个参数在这里是可选的,只有在
空元素可能出现在
双引号字段。)
用引号括起来:
map(嫀…›,''''''.v:val.'')
并将它们按顺序连接起来,与
分隔逗号:
join(嫀…›,,'))
结合这些步骤,我们得到了表达式
join(映射(拆分(子匹配(1),,,,,,,,,,,,,,,,,,,,,,,,,)
3.第二个是表达式Q
没有比这复杂得多;它只是一个替代品(内部)
替换,如Q
在:s
命令中)。任我们支配
我们有一个substitute()
函数,它的幂等于
同名命令
表情
替换(子匹配(1),“[^,]\+”,“&”“g”)
导致所有出现的非空字符序列都不存在
包含逗号,用单引号将其自身更改为逗号
在两端
如果我们希望此表达式也处理空列表项(如
上面的第一个变体是),我们只需要更改最后一个
模式到
“\%(^\\\,\)\zs[^,]*”
这样,它也允许空序列,但受
它们要么在开头,要么在逗号之后。(请参见:help\zs
和:帮助\%(
以更好地了解更改的模式是如何工作的。)
4.因此,我们可以使用以下两个命令之一:
:%s/“\([^”]*\)“/\=”[”.join(映射(拆分(子匹配(1),“,”,1),“””.v:val.“”),“,”)。”/g
或
:%s/“\([^”]*\)“/\=”[”。替换(子匹配(1),“\%(^\\;,\)\zs[^,]*',“&','g')。]”/g
它们都适用于一行中所有带引号的字段。您有多少个这样的字段?它们是每行一个吗?正则表达式不能很好地匹配引号(即不能区分第一个和最后一个)虽然如果行中没有其他引号,您可能可以不受影响。每行至少有一个引号。实际上,这是一个csv文件。您能给出一个示例文件吗?给您。如果有不清楚的地方,请告诉我:)如果您知道字符串中正好有四个字段,我建议您使用宏。现在是我检查每个符号的含义的时候了,希望我能找到如何处理多个引号。@keelar regex在这方面的工作是错误的。它分辨不出(这个)>(那个)之间的区别“
因为它所做的一切都是模式匹配。它无法分辨哪一个是正确配对的。例如,这个或那个是正确引用的。然而,大多数符号都可以在:h模式搜索中找到,如果我可以接受一次替换一列这些字符串,这会使事情变得更简单吗?(例如,我想替换的列是第3列和第5列,我可以发布两个不同的find/replace来转换它们)@keelar如果你能将它们转换为work@keelar我添加了一个函数,无论行中有多少对引号,它都应该一次完成整个文件。不知道你是否还需要它,但我认为它值得分享。非常感谢!这也行!你能再进一步解释一下吗?@keelar:当然。我已经添加了一个详细的解释,以及相同单通道方法的第二个实现。请告诉我你对此有何看法。我希望你会觉得它有帮助。