正则表达式Perl期间报价

时间:2012-04-16 08:42:04

标签: regex perl match period

在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;

不起作用

3 个答案:

答案 0 :(得分:6)

(\d+|\.+)表示一个或多个数字或一个或多个句点。但你想要的是([\d.]+),这意味着一个或多个数字或句号。

类似的问题也可以用于捕获大小和项目。您也错误地使用了起始锚点(^)和结束锚点($)。

您可以尝试:

^\s+([\d.]+)\s+(\d+)\s+([\d.]+)\s+"([^"]+)"\s*\((\d+)\s*

See it

答案 1 :(得分:2)

如果引用了所有第4行条目,

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!