在 Perl 中区分和替换小数

Distinguishing and substituting decimals in Perl

我想在文件中将小数点从逗号替换为句号,我想尝试在 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"; 

但是,当我尝试这样做时,发生的事情是我所有的逗号都变成了句号,而不仅仅是我的目标逗号。是正则表达式的问题还是我没有正确进行匹配替换?

谢谢!

这个:

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

产量:

Species_1:0.12, Species_2:0.23, Species_3:2.53

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

您的代码不起作用,因为您首先检查了数字包围的逗号,如果没问题,然后将所有逗号替换为点

从显示的数据来看,要替换的逗号似乎必须始终在每一侧都有一个数字,并且每次出现这种情况都需要替换。有罚款.

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

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

这应该更有效,因为没有复制到 </code> 和 <code> 也没有量词。

我的基准

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+)/./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%   --

这只是一个特别的字符串,但效率优势只会随着字符串的长度而增加,而较长的模式(此处为数字)应该会稍微降低一点。