我有一个CSV文件,其格式如下
(rupert, paul, 23, 8, [{fin, dan, jack},{bill,34,26,49},{84,28}],{34,jack,bon})
“{}”和“[]”中的CSV应替换为竖线字符“|”。格式化的输出应如下所示。
(rupert, paul, 23, 8, [{fin| dan| jack}|{bill|34|26|49}|{84|28}],{34|jack|bon})
我想使用Perl正则表达式,但我无处可去。非常感谢任何帮助。
perl guru提供的解决方案适用于单{}但是我发现自由流动的文本有一些嵌套的{}。我尝试修改perl onliner以适应嵌套的花括号,但没有成功。
(1,2,DER,赌注,NA,4,5-,{A,B,1,2-,SD [{1,2},{4,5}],C {Q,EW,3, 4},1,2,3-,CF {2,4,5,8},6}。
解决方案
(1,2,DER,赌注,NA,4,5-,{A,B,1,2-,SD [{1 | 2},{4 | 5}],C {Q | EW | 3 | 4},1,2,3-,CF {2 | 4 | 5 | 8} |。6}
但需要的是
(1,2,DER,赌注,NA,4,5-,{A | B | 1 | 2 | SD [{1 | 2} | {4 | 5}] | C {Q | EW | 3 | 4} | 1 | 2 | 3 | CF {2 | 4 | 5 | 8} |。6}
提前致谢。
答案 0 :(得分:3)
您可以使用正则表达式来检查逗号后面是]
还是}
,而不是前面的。{/ p>
my $s = "(rupert, paul, 23, 8, [{fin, dan, jack},{bill,34,26,49},{84,28}],{34,jack,bon})\n(rupert, paul, 23, 8, [{fin| dan| jack}|{bill|34|26|49}|{84|28}],{34|jack|bon})";
$s =~ s/,(?=(?:\{[^{}]*\}|[^{}])*})|,(?=(?:\[[^\[\]]*\]|[^\[\]])*\])/|/g;
print "$s\n";
请参阅IDEONE demo
答案 1 :(得分:2)
您可以逐字逐句地查看字符串,记住您在括号中的深度,并在需要时用竖线替换逗号。
#!/usr/bin/perl
use warnings;
use strict;
my $string = '(rupert, paul, 23, 8, [{fin, dan, jack},{bill,34,26,49},{84,28}],{34,jack,bon})';
my $inside;
for my $pos (0 .. length($string) - 1) {
my $char = substr $string, $pos, 1;
$inside++ if $char =~ /[[{]/;
$inside-- if $char =~ /[]}]/;
substr $string, $pos, 1, '|' if ',' eq $char && $inside;
}
print $string, "\n";
答案 2 :(得分:0)