Perl Map功能

时间:2010-06-26 19:03:34

标签: perl

我是地图和grep函数的新手,我正在尝试使现有脚本更简洁。

我可以成功地“grep”@tracknames,但我遇到了“map”的问题。我希望@trackartist返回true,如果在一行中找到两个连续的“ - ”并取值$ 1,否则为false,但如果不满足上限条件则返回整行。 我做错了什么?

my @tracknames = grep /^\d\d\..*?(\.(?:flac|wv))$/, <*.*>;
my @trackartist = map { s/^\d\d\.\s(.*?)\s--.*?\.(?:flac|wv)$/$1/; $_; } <*.*>;

Sample of files
01. some track artist 1 -- some track name 1.(flac or wv)
02. some track artist 2 -- some track name 2.(flac or wv)
03. some track artist 3 -- some track name 3.(flac or wv)
etc.

2 个答案:

答案 0 :(得分:6)

请记住,grep用于过滤列表,map用于转换列表。现在,您的map语句会为列表中的每个项目返回$_。如果$_与替换中的模式匹配,则会对其进行修改并替换为第一个匹配项。否则,它不会被修改,并返回原始的$_

听起来您想过滤掉与模式不匹配的项目。一种方法是组合地图和grep:

my @trackartist = map { s/^\d\d\.\s(.*?)\s--.*?\.(?:flac|wv)$/$1/; $_; }
                  grep { /^\d\d\.\s(.*?)\s--.*?\.(?:flac|wv)$/ } <*.*>;

当然,这意味着您正在进行两次相同的模式匹配。另一种方法是使用map进行转换,但将与模式不匹配的任何内容转换为空列表。

my @trackartist = map { /^\d\d\.\s(.*?)\s--.*?\.(?:flac|wv)$/ ? $1 : ( ) } <*.*>

这使用三元条件运算符(?:)来检查正则表达式是否匹配(返回真值)。如果是,则从$1块返回map,否则返回空列表( ),这不会对map生成的列表添加任何内容。< / p>

作为旁注,您可能希望使用glob函数而不是<>,这有一些缺点。

答案 1 :(得分:2)

我喜欢mapgrep和下一个人一样,但你的任务似乎更适合分而治之的解析方法。我之所以这样说,是因为您的评论表明您对map的兴趣正在引导您走上一条由平行数组组成的数据模型的道路 - @tracks@artists,等 - 从长远来看通常难以维持。这是我的意思草图:

my @tracks;

while (my $file_name = <DATA>){ # You'll use glob() or <*.*>
    # Filter out unwanted files.
    my ($num, $artist_title, $ext) = $file_name =~ /
        ^ (\d\d) \. \s*
        (.*)
        \. (flac|wv) $
    /x;
    next unless $ext;

    # Try to parse the artist and title. Adjust as needed.
    my ($artist, $title) = split /\s+--\s+/, $artist_title, 2;
    ($artist, $title) = ('UNKNOWN', $artist) unless $title;

    # Store all info as a hash ref. No need for parallel arrays.
    push @tracks, {
        file_name  => $file_name,
        ext        => $ext,
        artist     => $artist,
        title      => $title,
    };
}

__DATA__
01. Perl Jam -- Open or die.wv
02. Perl Jam -- Map to nowhere.flac
03. Perl Jam -- What the #$@!?.wv
04. Perl Jam -- Regex blues.wv
05. Perl Jam -- Use my package, baby.wv
06. Perl Jam -- No warnings.wv
07. Perl Jam -- Laziness ISA virtue.wv
08. Guido and the Pythons -- Home on the xrange.flac
09. Guido and the Pythons -- You gotta keep em generated.flac
10. StackOverflow medley.wv
foo.txt