我有$string = ABC_RPM_LOL
和GELO_FRE_OPN
之类的内容
我想提取ABC
和GELO
。 (第一个下划线之前的单词)。
使用Perl实现此目的的最快方式是什么?
答案 0 :(得分:5)
你可以使用的正则表达式是:
$string =~ /^([A-Z]+)_/;
$value = $1;
这假设您的单词仅由大写字母组成。如果它们是混合大小写,请在正则表达式的末尾抛出i
:/^([A-Z]+)_/i
。
修改:由于您要求最快捷的方式,这里是比较我的正则表达式和Lazarus's split
的基准:
#!perl
use strict;
use warnings;
use Benchmark qw/ :all /;
my $string = "ABC_RPM_LOL";
my $value;
my $count = 10_000_000;
cmpthese( $count, {
'regex' => sub { $string =~ /^([A-Z]+)_/; $value = $1; },
'split' => sub { ($value) = split /_/, $string; }
});
结果:
Rate regex split
regex 1869159/s -- -29%
split 2624672/s 40% --
所以split
更快了。
编辑第二个:我在此处添加了三个其他答案:
'split2' => sub { $value = (split('_',$string))[0]; },
'split3' => sub { ($value) = split /_/, $string, 2; },
'substr' => sub { $value = substr $string, 0, index $string, '_'; },
新结果:
Rate regex split2 split3 split substr
regex 1848429/s -- -8% -27% -28% -63%
split2 2008032/s 9% -- -21% -22% -60%
split3 2538071/s 37% 26% -- -1% -50%
split 2570694/s 39% 28% 1% -- -49%
substr 5050505/s 173% 152% 99% 96% --
答案 1 :(得分:3)
我的经验告诉我,罗恩是编程新手。
“最快”很少与“最佳”相对应......
但是,如果我们真的想要最快,我会从substr / index开始:
my $word1 = substr $_, 0, index $_, '_';
如果我认为“最快”并不是一个过早优化的简单案例,那么我会采用几种不同的方式来回答这个问题。
答案 2 :(得分:2)
不需要将split
字符串分成两个以上。
当split
指定了可选的第三个参数时,它将使用它来限制结果字符串的数量(以及随后完成的工作):
my ( $word ) = split /_/, $str, 2;
答案 3 :(得分:1)
我不会使用正则表达式,简陋的split
函数是你的朋友。
$extract = (split(/_/, $string))[0];
答案 4 :(得分:1)
你需要像
这样的东西$abc = split('_', $string)[0] # when string = ABC_RPM_LOL
$gelo = split('_', $string)[0] # when string = GELO_FRE_OPN
答案 5 :(得分:1)
一种方式:
#!/usr/bin/env perl
use strict;
use warnings;
my $string="ABC_RPM_LOL and GELO_FRE_OPN";
my @list = ( $string =~ m{(?:\b|\s)(\w+?)_}g );
print "@list\n";