在Perl中区分和替换小数

时间:2018-12-02 20:56:46

标签: regex perl substitution

我想用逗号将小数点替换为文件中的句号,我想尝试在perl中做到这一点。 我的数据集的示例如下所示:

Species_1:0,12, Species_2:0,23, Species_3:2,53

我想用小数代替而不是所有逗号,例如:

Species_1:0.12, Species_2:0.23, Species_3:2.53

我当时认为使用替换功能可能会起作用:

$comma_file= "Species_1:0,12 , Species_2:0,23, Species_3:2,53"

    $comma = "(:\d+/,\d)";
#match a colon, any digits after the colon, the wanted comma and digits preceding it
       if ($comma_file =~ m/$comma/g) {
           $comma_file =~ tr/,/./;
        }
print "$comma_file\n"; 

但是,当我尝试此操作时,发生的是我所有的逗号都变成了句号,而不仅仅是我所针对的逗号。正则表达式有问题还是我只是没有正确进行比赛替换?

谢谢!

2 个答案:

答案 0 :(得分:3)

此:

use strict;
use warnings;
my $comma_file = "Species_1:0,12, Species_2:0,23, Species_3:2,53";
$comma_file =~ s/(\d+),(\d+)/$1.$2/g;
print $comma_file, "\n";

收益:

Species_1:0.12, Species_2:0.23, Species_3:2.53

正则表达式搜索两边至少有一位数字的逗号,并用点代替。

您的代码无效,因为您先检查数字是否包含逗号,如果可以,则将所有逗号替换为点

答案 1 :(得分:2)

从显示的数据来看,要替换的逗号似乎总是必须在每侧都有一个数字,并且每次出现这种情况都需要替换。 answer by GMB很好。

解决此类问题的另一种方法是使用lookarounds

$comma_file =~ s/(?<=[0-9]),(?=[0-9])/./g;

应该更有效,因为不会复制到$1$2中,也没有量词。

我的基准

use warnings;
use strict;
use feature 'say';

use Benchmark qw(cmpthese);

my $str = q(Species_1:0,12, Species_2:0,23, Species_3:2,53);

sub subs {
    my ($str) = @_; 
    $str =~ s/(\d+),(\d+)/$1.$2/g;
    return $str;
}

sub look {
    my ($str) = @_; 
    $str =~ s/(?<=\d),(?=\d)/./g;
    return $str;
}

die "Output not equal" if subs($str) ne look($str);

cmpthese(-3, {
    subs => sub { my $res = subs($str) },
    look => sub { my $res = look($str) },
});

有输出

         Rate subs look
subs 256126/s   -- -46%
look 472677/s  85%   --

这只是一个特别的字符串,但是效率优势仅应随着字符串的长度增加,而更长的模式(此处为数字)则应减少一点。