在Perl中使用正则表达式尝试N + 1次后: 我有以下问题: 我需要检索这个:
232310..1.3 3213 2.4 "$250 For My jacket" (2012)
我试图通过以下方式检索它:
if ( $line=~m/^\s+(\d+|\.+)\s+(\d+)\s+(\d+|\.+)\s+(\^"&(\w*|\s*|\D*)"$)\s*\((\d+)\s*/){
$ID=$1;
$Amount=$2;
$Size=$3;
$Item=$4;
$Year=$5;
不起作用
答案 0 :(得分:6)
(\d+|\.+)
表示一个或多个数字或一个或多个句点。但你想要的是([\d.]+)
,这意味着一个或多个数字或句号。
类似的问题也可以用于捕获大小和项目。您也错误地使用了起始锚点(^
)和结束锚点($
)。
您可以尝试:
^\s+([\d.]+)\s+(\d+)\s+([\d.]+)\s+"([^"]+)"\s*\((\d+)\s*
答案 1 :(得分:2)
codaddict的解决方案就可以了。 另一种方法是使用CSV解析器(您可能需要先从CPAN安装), 例如:
#!/usr/bin/env perl
use strict;
use warnings;
use Text::CSV_XS;
my $csvr = new Text::CSV_XS({
sep_char => ' ',
eol => $/
});
my $csvw = new Text::CSV_XS({
sep_char => ',',
eol => $/
});
$csvw->print( *STDOUT, [ qw(ID Amount Size Item Year) ]);
while (my $row = $csvr->getline(*ARGV))
{
$csvw->print( *STDOUT, [ grep { /./ } @$row ] );
}
}
给出输入
232310..1.3 3213 2.4 "$250 For My jacket" (2012)
这会产生:
232310..1.3,3213,2.4,"$250 For My jacket",(2012)
进一步的步骤是使用DBD::CSV
,它允许您对输入文件执行SQL查询。
答案 2 :(得分:1)
与codaddict相同,但展示了如何使正则表达式更具可读性 - 'x'选项对于更长的正则表达式和多个捕获变量非常有用。
(我会将此作为评论发布,但对于有限的格式选项)
my ( $id, $amount, $size, $item, $year ) = $line =~ m{
^
\s+
([\d.]+) # field 1, e.g. 232310..1.3
\s+
(\d+) # field 2, e.g. 3213
\s+
([\d.]+) # field 3, e.g. 2.4
\s+
"([^"]+)" # field 4, e.g. "$250 For My jacket"
\s*
\((\d+)\) # field 5, e.g. (2012)
\s*
}x or die "Line does not match!"; # always check that a regex actually succeeded!