简体   繁体   English

Perl分裂并弹出一行

[英]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. pushpopshiftunshift用于操作数组。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM