[英]Perl split and pop in one line
I'm trying to split a string and pop a value off of the returned array. 我正在尝试拆分一个字符串并从返回的数组中弹出一个值。 How can I do this in one line?
我怎么能在一行中做到这一点?
my $string = 'test,string';
# Split and pop in one line
my $val = pop [split ',', $string];
print $val;
The result should be 'string'
but instead I am getting this: 结果应该是
'string'
但我得到这个:
Type of arg 1 to pop must be array (not anonymous list ([]))
弹出的arg 1的类型必须是数组(不是匿名列表([]))
Here's my Perl version information in case it helps: 这是我的Perl版本信息,以防它有用:
This is perl, v5.8.8 built for x86_64-linux-thread-multi
这是为x86_64-linux-thread-multi构建的perl,v5.8.8
push
, pop
, shift
, and unshift
are for manipulating arrays. push
, pop
, shift
和unshift
用于操作数组。 It sounds like you just want to get the last value from the list returned by split
, which you can get with a list slice: 听起来你只想从
split
返回的列表中获取最后一个值,您可以使用列表切片获得:
my $val = (split /,/, $foo)[-1];
[]
返回对数组的引用,但pop
需要一个实际的数组,因此解决方案是取消引用数组,如下所示:
my $val = pop @{[split ',', $string]};
If your intent is to get the last field after some number of commas, there are multiple way -- some way faster than others. 如果你的意图是在一些逗号之后得到最后一个字段,那么有多种方式 - 某种方式比其他方式更快。
A greedy regex with a delimiter pattern + field pattern would be common, easy to read, and fast: 具有分隔符模式+字段模式的贪婪正则表达式将是常见的,易于阅读和快速:
/.*(delimiter pattern)(field_pattern)/
The .*
sucks ups all characters except the last instance of the delimiter. .*
吸收除分隔符的最后一个实例之外的所有字符。 Then the field pattern returns the last field. 然后字段模式返回最后一个字段。
Using an anchored split (so that only two parts are returned) is also idiomatic: 使用锚定分割(这样只返回两个部分)也是惯用的:
my ($lh, $rh)=split(/([^,]+)$/, $string);
Now $rh
has the last element of the split (and $lh
has the part to the left of the last field). 现在
$rh
具有拆分的最后一个元素( $lh
具有最后一个字段左边的部分)。
The fastest (if $string
is longish and your delimiter is invariant) would be something like: 最快的 (如果
$string
是长的,你的分隔符是不变的)将是这样的:
substr $string, rindex( $string, ',' ) + length ',';
Benchmark of these and some other methods for curiosity: 这些以及其他好奇心方法的基准:
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";
}
Prints: 打印:
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% --
You can see that rindex is by far the fastest with a greedy regex a very useable second. 你可以看到rindex是最快的,贪婪的正则表达式是一个非常有用的秒。 If the string are few and short, I suppose you can use any that balance out idiom and readability and that is your solution.
如果字符串很少而且很短,我想你可以使用任何平衡成语和可读性,这是你的解决方案。
If efficiency is a concern, just use a regex. 如果效率是一个问题,只需使用正则表达式。 Splitting strings and popping arrays is (potentially) expensive.
拆分字符串和弹出数组(可能)很昂贵。
my ($val) = $string =~ /,(\w+)$/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.