将替换应用于grep返回的第一个项目

时间:2018-01-15 16:12:28

标签: perl grep substitution

我有这个程序

sub f {                                                                                                                                                                                                                       
    return ("A/X", "B/X");                                                                                                   
}                                                                                                                            

$x = grep( /X$/, f() ) =~ s/\/X$//r;                                                                                           
print "$x\n";                                                                                                                

($x) = grep( /X$/, f() ) =~ s/\/X$//r;                                                                                         
print "$x\n";                                                                                                                

( ($x) = grep( /X$/, f() ) ) =~ s/\/X$//;                                                                                        
print "$x\n";                                                                                                                

($x) = grep( /X$/, f() );                                                                                                      
$x =~ s/\/X//;                                                                                                               
print "$x\n";

结果是

2
2
A/X
A

我想要的结果是

A

但只有最后一次尝试才能产生它。

在我的完整程序中,我想用一行来完成这个,因为我必须多次这样做。我想避免像$x[0]这样的事情和f()是一个更复杂的功能

我该怎么做?

1 个答案:

答案 0 :(得分:5)

my ($x) = map { s{/X$}{}r } grep { /X$/ } f();

my $x = ( grep { /X$/ } f() )[0] =~ s{/X$}{}r;

use List::Util qw( first );

my $x = ( first { /X$/ } f() ) =~ s{/X$}{}r;

如果$x没有返回任何内容,则第一个将undef静默设置为f(),而其他两个将$x设置为空字符串,并在该情况下发出警告。第二个避免了不必要的工作。第三个避免更多。

顺便说一下,你要求相当于以下

my ($x) = map { s{/X$}{}r } grep { m{X$} } f();

但我认为你想要以下内容:

my ($x) = map { s{/X$}{}r } grep { m{/X$} } f();

让我们避免重复,以免再犯错误!

my ($x) = map { my $s=$_; $s =~ s{/X$}{} ? $s : () } f();

use File::Basename qw( fileparse );

my ($x) = map { my ($fn, $dir_qn) = fileparse($_); $fn eq 'X' ? $dir_qn : () }  f();