分割一个逗号分隔的列表,其中文本的逗号不能转义

时间:2019-02-15 16:54:03

标签: regex perl

我正在处理通常为以下格式的旧数据:

QID    RESPONSE

但是在某些情况下,响应包含多个不同类型的值:

01320   2,35,6,"warm"

我尝试使用

my @dataRowAsList = split('\t', $_); 
my $questionID = $dataRowAsList[0];     
my $response = substr($dataRowAsList[1],0,-2);
my @thisResponse = split(',', $response);

在相关案例中将输出分为问题和响应,然后将每个响应分为各个组成部分

但是我刚刚发现了这种情况:

01320   2,35,6,"warm,windy"

引号中的逗号不能转义

是否有一种巧妙的方法可以将其解析为其组件?

2
35
6
"warm,windy"

2 个答案:

答案 0 :(得分:9)

使用Text::CSV来读取字符串的快速示例:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw/say/;
use Text::CSV;

my $str = q/01320   2,35,6,"warm,windy"/;

my $csv = Text::CSV->new({auto_diag => 2});

my @fields = split " ", $str, 2;

say '$fields[0] is ', $fields[0];
say '$fields[1] is ', $fields[1];

say 'Parsed out $fields[1] is:';
$csv->parse($fields[1]);
say for $csv->fields;

运行此操作将产生:

$fields[0] is 01320
$fields[1] is 2,35,6,"warm,windy"
Parsed out $fields[1] is:
2
35
6
warm,windy

这是一个非核心模块,因此您必须使用自己喜欢的CPAN客户端或操作系统的软件包管理器进行安装。如果这样做还不能自动安装Text::CSV_XS,那么您可能也想这样做,以获得Text::CSV可以自动使用的优化实现。

答案 1 :(得分:-1)

在您的情况下,我将使用regexp并检查所需的组,这是一个示例,希望对您有所帮助

use warnings;
use strict;
my $string = '01320 2,35,6,"warm,windy"';

if ($string =~ /^(\d+)\t(\d+),{1}(\d+),{1}(\d+),{1}(\S+)$/gu) {
        print "$1\n$2\n$3\n$4\n$5\n\n";
}