Perl:使用split但忽略引号

h q*_*h q 0 regex perl hash split

我正在尝试从输入字符串创建一个Perl哈希,但是我遇到了原始'split'的问题,因为值可能包含引号.下面是一个示例输入字符串,以及我的(所需)结果哈希:

my $command = 'CREATE:USER:TEL,12345678:MOB,444001122:Type,Whatever:ATTRIBUTES,"ID,0,MOB,123,KEY,VALUE":TIME,"08:01:59":FIN,0';

my %hash = 
  (
   CREATE     => '',
   USER       => '',
   TEL        => '12345678',
   MOB        => '444001122',
   Type       => 'Whatever',
   ATTRIBUTES => 'ID,0,MOB,123,KEY,VALUE',
   TIME       => '08:01:59',
   FIN        => '0',
  );
Run Code Online (Sandbox Code Playgroud)

输入字符串具有任意长度,并且未设置键的数量.

谢谢!

-hq

cho*_*oba 5

使用Text :: CSV.它正确处理逗号分隔值文件.

更新

看来您的输入格式无法通过标准模块进行解析,即使使用sep_charallow_loose_quotes.因此,您必须自己进行繁重的工作,但仍然可以使用Text :: CSV来解析每个键值对:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw(say);

use Data::Dumper;

use Text::CSV;

my $command = 'CREATE:USER:TEL,12345678:MOB,444001122:Type,Whatever:ATTRIBUTES,"ID,0,KEY,VALUE":TIME,"08:01:59":FIN,0';

my @fields = split /:/, $command;
my %hash;
my $csv = Text::CSV->new();

my $i = 0;
while ($i <= $#fields) {
    if (1 == $fields[$i] =~ y/"//) {
        my $j = $i;
        $fields[$i] .= ':' . $fields[$j] until 1 == $fields[++$j] =~ y/"//;
        $fields[$i] .= ':' . $fields[$j];
        splice @fields, $i + 1, $j - $i, ();
    }
    $csv->parse($fields[$i]);
    my ($key, $value) = $csv->fields;
    $hash{$key} = "$value"; # quotes turn undef to q()
    $i++;
}

print Dumper \%hash;
Run Code Online (Sandbox Code Playgroud)