Perl 在一行中拆分和弹出
Perl split and pop in one line
我正在尝试拆分一个字符串并从返回的数组中弹出一个值。我怎样才能在一行中做到这一点?
my $string = 'test,string';
# Split and pop in one line
my $val = pop [split ',', $string];
print $val;
结果应该是 'string'
但我得到的是:
Type of arg 1 to pop must be array (not anonymous list ([]))
这是我的 Perl 版本信息,希望对您有所帮助:
This is perl, v5.8.8 built for x86_64-linux-thread-multi
[]
returns 对数组的引用,但 pop
需要一个实际的数组,因此解决方案是取消对数组的引用,如下所示:
my $val = pop @{[split ',', $string]};
push
、pop
、shift
和unshift
用于操作数组。听起来您只想从 split
返回的列表中获取最后一个值,您可以使用列表切片获取它:
my $val = (split /,/, $foo)[-1];
如果担心效率,只需使用正则表达式即可。拆分字符串和弹出数组(可能)很昂贵。
my ($val) = $string =~ /,(\w+)$/
如果您的目的是在一定数量的逗号之后获取最后一个字段,则有多种方式 - 有些方式比其他方式更快。
带有定界符模式 + 字段模式的贪婪正则表达式很常见,易于阅读且速度快:
/.*(delimiter pattern)(field_pattern)/
.*
吸取除最后一个定界符以外的所有字符。然后字段模式returns 最后一个字段.
使用锚定拆分(以便只返回两个部分)也是惯用的:
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 是迄今为止最快的,贪婪的正则表达式非常有用。如果字符串又少又短,我想您可以使用任何可以平衡成语和可读性的字符串,这就是您的解决方案。
我正在尝试拆分一个字符串并从返回的数组中弹出一个值。我怎样才能在一行中做到这一点?
my $string = 'test,string';
# Split and pop in one line
my $val = pop [split ',', $string];
print $val;
结果应该是 'string'
但我得到的是:
Type of arg 1 to pop must be array (not anonymous list ([]))
这是我的 Perl 版本信息,希望对您有所帮助:
This is perl, v5.8.8 built for x86_64-linux-thread-multi
[]
returns 对数组的引用,但 pop
需要一个实际的数组,因此解决方案是取消对数组的引用,如下所示:
my $val = pop @{[split ',', $string]};
push
、pop
、shift
和unshift
用于操作数组。听起来您只想从 split
返回的列表中获取最后一个值,您可以使用列表切片获取它:
my $val = (split /,/, $foo)[-1];
如果担心效率,只需使用正则表达式即可。拆分字符串和弹出数组(可能)很昂贵。
my ($val) = $string =~ /,(\w+)$/
如果您的目的是在一定数量的逗号之后获取最后一个字段,则有多种方式 - 有些方式比其他方式更快。
带有定界符模式 + 字段模式的贪婪正则表达式很常见,易于阅读且速度快:
/.*(delimiter pattern)(field_pattern)/
.*
吸取除最后一个定界符以外的所有字符。然后字段模式returns 最后一个字段.
使用锚定拆分(以便只返回两个部分)也是惯用的:
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 是迄今为止最快的,贪婪的正则表达式非常有用。如果字符串又少又短,我想您可以使用任何可以平衡成语和可读性的字符串,这就是您的解决方案。