如何修改这个 Perl 解决方案,以便它将嵌入的双引号替换为单引号?

如何修改这个 Perl 解决方案,以便它将嵌入的双引号替换为单引号?

之前在这个问题中:“除了括起来的引号之外,字符串之间还有双引号“ @BernieReiter 提出了一个后续问题,他想要获取如下所示的 CSV 条目:

$ cat test.csv
17,"abc","Testurteil "sehr gut"","08/15"
99,"xyz","Testurteil "vernichtend"","4711"

并将它们转换"..."为单引号 (),而不是嵌入双引号 ( '...')。

结果应该如下所示:

17,"abc","Testurteil 'sehr gut'","08/15"
99,"xyz","Testurteil 'vernichtend'","4711"

@BernieReiter 还询问他如何采用他为该问题提供的 @StephaneChazelas 解决方案,他在其中使用了这个 Perl 解决方案:

$ perl -pi.back -le 's/"(?:[^"]|"(?=[^,]))*"|[^",]*/($r=$&)=~
  s@(^"|"$|\\.)|"@$1||"\\\""@ge;$r/ge' file.csv

那么如何修改斯蒂芬的解决方案呢?

答案1

对 @Stephane 解决方案的以下修改似乎提供了 @BernieReiter 正在寻找的内容:

$ perl -pi.back -le 's/"(?:[^"]|"(?=[^,]))*"|[^",]*/($r=$&)=~
  s@(^"|"$|\\.)|"@$1||"'\''"@ge;$r/ge' test.csv

在原始 Perl 解决方案中需要注意的关键是这个子组件:

s@(^"|"$|\\.)|"@$1||"\\\""@ge

具体来说这段代码:

"\\\""

这是围绕 的双引号块\\\"。这是 @Stephane 的原始解决方案的一部分,它替换了\"任何内部双引号。这就是发生的事情:

"Testurteil "sehr gut""

并将其变成这样:

"Testurteil \"sehr gut\""

因此,只需将双引号 ( ) 之间的内容替换"\\\""为单引号结构即可:

"'\''"

笔记:我们需要\'用单引号括起来以保护它!

最终解决方案

$ perl -pi.back -le 's/"(?:[^"]|"(?=[^,]))*"|[^",]*/($r=$&)=~
  s@(^"|"$|\\.)|"@$1||"'\''"@ge;$r/ge' file.csv

例子

运行此命令将按照最初指定的方式转换文件。

$ perl -pi.back -le 's/"(?:[^"]|"(?=[^,]))*"|[^",]*/($r=$&)=~
  s@(^"|"$|\\.)|"@$1||"'\''"@ge;$r/ge' test.csv

结果:

$ more test.csv
17,"abc","Testurteil 'sehr gut'","08/15"
99,"xyz","Testurteil 'vernichtend'","4711"

相关内容