我尝试拆分字符串并从返回的数组中弹出一个值。我怎么能在一行中做到这一点?
Activity
结果应为my $string = 'test,string';
# Split and pop in one line
my $val = pop [split ',', $string];
print $val;
,但我得到的是:
弹出的arg 1类型必须是数组(不是匿名列表([]))
这是我的Perl版本信息,以防它有用:
这是为x86_64-linux-thread-multi
构建的perl,v5.8.8
答案 0 :(得分:8)
push
,pop
,shift
和unshift
用于操作数组。听起来您只想从split
返回的列表中获取最后一个值,您可以使用列表切片获得该值:
my $val = (split /,/, $foo)[-1];
答案 1 :(得分:7)
[]
返回对数组的引用,但pop
需要一个实际数组,因此解决方案是取消引用数组,如下所示:
my $val = pop @{[split ',', $string]};
答案 2 :(得分:2)
如果你的意图是在一些逗号之后得到最后一个字段,那么有多种方式 - 某种方式比其他方式更快。
带有分隔符模式+字段模式的贪婪正则表达式很常见,易于阅读和快速:
/.*(delimiter pattern)(field_pattern)/
除了分隔符的最后一个实例之外,.*
吸收所有字符。然后字段模式返回最后一个字段。
使用锚定分割(这样只返回两个部分)也是惯用的:
my ($lh, $rh)=split(/([^,]+)$/, $string);
现在$rh
有分割的最后一个元素(而$lh
有最后一个字段左边的部分。)
最快的(如果$string
很长而你的分隔符是不变的)会是这样的:
substr $string, rindex( $string, ',' ) + length ',';
这些和其他好奇心方法的基准:
use strict;
use warnings;
use Benchmark;
my $str;
my %subs = (
regex => sub {
my ($rh) = $str =~ /,([^,]+)$/;
return $rh;
},
greedy_regex => sub {
my ($rh) = $str =~ /.*,([^,]+)$/;
return $rh;
},
split_once => sub {
my ($lh, $rh)=split(/([^,]+)$/, $str, 2);
return $rh;
},
split_slice => sub {
my ($rh) = (split /,/, $str)[-1];
return $rh;
},
pop => sub {
my ($rh) = pop @{[split ',', $str]};
return $rh;
},
rindex => sub {
my ($rh) = substr $str, rindex( $str, ',' ) + length ',';
return $rh;
}
);
for my $n (10, 100, 1000, 10000) {
$str=join(',', (1..$n));
my @results=();
for my $sub (keys %subs) {
my $ret=@{[$subs{$sub}()]}[0];
if ($ret ne $n){
print "$sub: $ret != $n\n";
}
else {
push @results, $sub;
}
}
my $l=length($str);
print join(', ', @results)," all returned \"$n\" from a string $l characters long\n";
Benchmark::cmpthese -1, \%subs;
print "\n";
}
打印:
split_once, pop, split_slice, regex, rindex, greedy_regex all returned "10" from a string 20 characters long
Rate pop split_once split_slice regex greedy_regex rindex
pop 295080/s -- -46% -49% -57% -86% -95%
split_once 546132/s 85% -- -5% -21% -75% -91%
split_slice 573439/s 94% 5% -- -17% -74% -91%
regex 689852/s 134% 26% 20% -- -68% -89%
greedy_regex 2182991/s 640% 300% 281% 216% -- -65%
rindex 6230669/s 2012% 1041% 987% 803% 185% --
split_once, pop, split_slice, regex, rindex, greedy_regex all returned "100" from a string 291 characters long
Rate pop split_slice regex split_once greedy_regex rindex
pop 29020/s -- -50% -54% -54% -98% -100%
split_slice 57961/s 100% -- -8% -9% -96% -99%
regex 63015/s 117% 9% -- -1% -96% -99%
split_once 63433/s 119% 9% 1% -- -96% -99%
greedy_regex 1536000/s 5193% 2550% 2338% 2321% -- -75%
rindex 6068148/s 20810% 10369% 9530% 9466% 295% --
split_once, pop, split_slice, regex, rindex, greedy_regex all returned "1000" from a string 3892 characters long
Rate pop regex split_once split_slice greedy_regex rindex
pop 3428/s -- -36% -40% -50% -99% -100%
regex 5333/s 56% -- -7% -23% -99% -100%
split_once 5749/s 68% 8% -- -17% -99% -100%
split_slice 6892/s 101% 29% 20% -- -98% -100%
greedy_regex 417552/s 12082% 7730% 7163% 5958% -- -93%
rindex 6036210/s 176002% 113085% 104894% 87479% 1346% --
split_once, pop, split_slice, regex, rindex, greedy_regex all returned "10000" from a string 48893 characters long
Rate pop regex split_once split_slice greedy_regex rindex
pop 355/s -- -24% -29% -51% -99% -100%
regex 465/s 31% -- -7% -35% -99% -100%
split_once 501/s 41% 8% -- -30% -99% -100%
split_slice 718/s 102% 54% 43% -- -99% -100%
greedy_regex 59076/s 16530% 12603% 11692% 8126% -- -99%
rindex 5770465/s 1624294% 1240731% 1151756% 803382% 9668% --
greedy_regex, split_slice, split_once, regex, pop, rindex all returned correctly with "10000" from a string 48893 characters long
Rate pop split_once regex split_slice greedy_regex rindex
pop 383/s -- -26% -26% -45% -99% -100%
split_once 516/s 35% -- -0% -26% -99% -100%
regex 519/s 35% 0% -- -25% -99% -100%
split_slice 693/s 81% 34% 34% -- -99% -100%
greedy_regex 59076/s 15311% 11349% 11293% 8425% -- -99%
rindex 6109904/s 1593788% 1183990% 1178239% 881582% 10242% --
你可以看到rindex是最快的,贪婪的正则表达式是非常有用的第二个。如果字符串很少而且很短,我想你可以使用任何平衡成语和可读性,这是你的解决方案。
答案 3 :(得分:1)
如果要考虑效率,请使用正则表达式。拆分字符串和弹出数组(可能)很昂贵。
my ($val) = $string =~ /,(\w+)$/