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:当然。我已经添加了一个详细的解释,以及相同单通道方法的第二个实现。请告诉我你对此有何看法。我希望你会觉得它有帮助。