简化perl map和grep

时间:2016-03-02 18:00:52

标签: perl map-function

我需要在某些集合的所有行中找到特定的子文本,我最终得到了这个:

my @missing = grep { $_ ne '' } map { $1 if m/^prefix:\s+(.+):\s+suffix$/ } @lines;

哪个工作正常。但是一开始的那个grep(为了摆脱比赛没有发生的所有情绪线)看起来很糟糕。

有更清洁的方法吗?

只是为了澄清,这里是示例输入和没有grep的输出:

my @lines = (
    'drivel',
    'prefix: matches: suffix',
    'stuff',
    'prefix: more: suffix'
);

my @selected = map { $1 if m/^prefix:\s+(.+):\s+suffix$/ } @lines;
print "found: $_\n" foreach @selected;

想要输出:

found: matches
found: more

输出得到以上:

found:
found: matches
found:
found: more

3 个答案:

答案 0 :(得分:8)

在地图中返回()并不会将任何元素添加到输出中,因此您可以使用三元条件,例如

my @missing = map { m/^prefix:\s+(.+):\s+suffix$/ ? $1 : () } @lines;

m/...(...).../已经在匹配上返回非空列表,否则返回空列表,所以我想你可以说

my @missing = map { m/^prefix:\s+(.+):\s+suffix$/ } @lines;

答案 1 :(得分:3)

我认为你可以通过在找不到匹配项时返回空列表来处理map所有内容:

my @missing = map { /^prefix:\s+(.+):\s+suffix$/ ? $1 : () } @lines;

答案 2 :(得分:0)

不等于更简单:

my @missing = grep /./, map { $1 if m/^prefix:\s+(.+):\s+suffix$/ } @lines;