如果陣列不能包含哈希,以下可能是解決方法:
use warnings;
use strict;
use JSON::XS;
use Text::Balanced qw(extract_bracketed extract_delimited);
use Text::CSV;
my $csv = Text::CSV->new({ sep_char => ',', allow_whitespace => 1 });
my $h = { a => "[", g => [ "[", 2, "bb]]", 4 ], b => 3, c => [ 1, 2, 3, 4 ] };
my $coder = JSON::XS->new->pretty;
my $txt = $coder->encode($h);
my $str = "";
while (1) {
my $ind1 = index($txt, '"');
my $ind2 = index($txt, '[');
if ($ind1 >= 0 && $ind2 >= 0) {
if ($ind1 < $ind2) {
skipQuoted(\$txt, \$str);
next;
}
}
elsif ($ind2 < 0) {
$str .= $txt;
last;
}
my ($etxt, $end, $beg) = extract_bracketed($txt, '["]', '[^[]*');
die "Unexpected!" if !defined $etxt;
$str .= $beg;
$etxt = substr($etxt, 1, length($etxt) - 2)
; #strip leading and trailing brackets
$etxt =~ s{\n}{}g;
my @elem;
if ($csv->parse($etxt)) {
@elem = $csv->fields();
}
else {
die "Unexpected!";
}
$str .= '[ ' . processFields(\@elem) . ' ]';
$txt = $end;
}
print $str;
sub skipQuoted {
my ($txt, $str) = @_;
my ($s1, $s2, $s3) = extract_delimited($$txt, '"', '[^"]*');
die "Unexpected!" if !defined $s1;
$$str .= $s3 . $s1;
$$txt = $s2;
}
sub processFields {
my ($a) = @_;
for (@$a) {
if ($_ !~ /^-?(0|([1-9][0-9]*))(\.[0-9]+)?([eE][-+]?[0-9]+)?$/) {
$_ = '"' . $_ . '"';
}
}
return join(", ", @$a);
}
輸出:
{
"a" : "[",
"g" : [ "[", 2, "bb]]", 4 ],
"b" : 3,
"c" : [ 1, 2, 3, 4 ]
}
謝謝!這看起來不錯,但我找不到'XS.xs'文件。其他人(在其他機器上)也會使用這個程序,所以我認爲這不是一個在本地修改源代碼的選項。最好是提交給我認爲模塊作者的補丁。不管怎麼說,還是要謝謝你! – 2014-11-08 12:03:18
您是從CPAN手動安裝軟件包還是使用軟件包管理器?如果你是從軟件包安裝的,刪除它('rpm -e perl-JSON-XS'或類似的東西,取決於你的系統),然後用CPAN安裝:'perl -MCPAN -e'install JSON :: XS'' 。您將擁有一個帶有模塊源代碼的「build」目錄,包括'XS.xs'。 – afenster 2014-11-08 12:06:06
或者用這個補丁重建RPM也許更好。取決於你喜歡哪種方法。 – afenster 2014-11-08 12:06:31