【问题标题】:Is possible to use next inside of map in perl?可以在 perl 中使用 map 内部的 next 吗?
【发布时间】:2020-11-23 00:26:32
【问题描述】:

我只想解析 main.c 中的标题名称:

#include "foo.h"
#include "bar.h"
#include <stdio.h>

int add(int a,int b){ return a+b; }
int sub(int a, int b){ return a-b; }

int main(){
    printf("%i\n",add(1,2));
}

所以我的 perl 脚本如下所示:

#!/usr/bin/perl 
open MAIN, $ARGV[0];

@ar = map { /#include "([^"]+)"/ ? $1 : next } <MAIN>;

#this one works (next inside for-loop, not map-loop)
for(<MAIN>){
    if(/#include "([^"]+)"/){
        push @ar2, $1;
    } else {
        next;
    }
}

print "@ar\n";
print "@ar2\n";

给出错误:

Can't "next" outside a loop block 

那么next 可能在map 中吗?如果是这样,如何解决我的问题?

【问题讨论】:

  • 提示:始终使用use strict; use warnings;。还有其他可以改进的地方,但这一点至关重要。
  • for 循环中的next 之后没有更多操作,因此您实际上根本不需要else 块。

标签: arrays loops perl map-function


【解决方案1】:

map 的给定迭代可以返回任意数量的标量,包括零。

my @ar = map { /#include "([^"]+)"/ ? $1 : () } <MAIN>;

在列表上下文中带有捕获的匹配会在匹配时返回捕获的文本,而在匹配失败时则不返回任何内容。因此,上述内容可以简化。

my @ar = map { /#include "([^"]+)"/ } <MAIN>;

【讨论】:

  • 如果// 中有更多捕获怎么办?结果会返回 $1 还是 $2 ?
  • 两者。您始终可以使用条件运算符进行更多控制。例如,/^(.)\1(.)\2(.)\3\z/ ? ( $1, $3 ) : ()
  • 但是我不能使用$1 然后:如果我使用@main_hed=map{/#include "([^"]+)"/ and abs_path($1)}&lt;MAIN&gt;;,那么$1 将保留用于即使失败的那些。我必须使用for 而不是map
  • /#include "([^"]+)"/ ? abs_path($1) : ()
  • 你也可以链接maps。 map { abs_path($_) } map { /#include "([^"]+)"/ }
猜你喜欢
  • 1970-01-01
  • 2021-12-05
  • 2012-04-29
  • 1970-01-01
  • 2012-08-10
  • 2020-02-20
  • 2021-11-26
  • 1970-01-01
  • 2021-07-13
相关资源
最近更新 更多