Perl 将字符串转换为数字“;参数不是’;t编号错误”;

Perl 将字符串转换为数字“;参数不是’;t编号错误”;,perl,parsing,Perl,Parsing,我正在分析制表符分隔的文件。有几列虽然是数字,但没有被识别为数字。当我尝试对这些值求和时,会显示错误:参数“97”不是数字加法(+),Perl返回0 我尝试过使用Scalar::Util qw(看起来像数字)但它产生了相同的结果“0”。还有什么我可以试试的吗 代码如下: open my $out_fh, '>', $final_variants or die qq{Unable to open "$final_variants" for output: $!}; open my $in_

我正在分析制表符分隔的文件。有几列虽然是数字,但没有被识别为数字。当我尝试对这些值求和时,会显示错误:
参数“97”不是数字加法(+)
,Perl返回0

我尝试过使用
Scalar::Util qw(看起来像数字)但它产生了相同的结果“0”。还有什么我可以试试的吗

代码如下:

open my $out_fh, '>', $final_variants or die qq{Unable to open "$final_variants" for output: $!};

open my $in_fh, '<', $tsv_file_new
            or die qq{Unable to open "$tsv_file_new" for input: $!};

while ( <$in_fh> ) {

        my @fields = split;

        my $forward_reference = $fields[67];
        my $reverse_reference = $fields[68];
        my $forward_variant_reads = $fields[77];
        my $reverse_variant_reads = $fields[78];

        my $total_reads = (looks_like_number($forward_reference))
                + (looks_like_number($reverse_reference))
                + (looks_like_number($forward_variant_reads))
                + (looks_like_number($reverse_variant_reads));

        my $current_final_line = $headerline . "\t"
                    . $forward_reference . "\t"
                    . $reverse_reference . "\t"
                    . $forward_variant_reads . "\t"
                    . $reverse_variant_reads . "\t"
                    . $total_reads . "\t";

        print $out_fh $current_final_line, "\n";
}
打开我的$out\u fh,'>',$final\u变体或死亡qq{无法打开输出的“$final\u变体:$!};

打开我的$in_fh,“这个错误是由于额外的引号引起的,但我首先要提到一个编码问题。通过执行类似于数字($var)+…
的操作来添加值是一个错误。 从,

如果perl认为EXPR是一个数字,则返回true

它用于测试变量是否为数字。它返回零或大的正整数。因此,您需要首先测试哪些是数字,例如通过过滤,然后才将它们用作数字

正如在中所解释的,很明显,有额外的引用。然而,我会小心地删除所有的引号,因为你可能会暴露一些确实不是数字的东西。此外,如果涉及其他处理,则可能需要字符串中可能的引号

最后,我还是会测试变量,清除引号,通过
looks\u like\u number
来组合那些数字变量。或许

use List::Util qw(sum);
# Remove extra (leading and trailing) quotes, for example
my @references   = map { s/^"//; s/"$//; $_ } ($forward_reference, ...);
my @numeric_refs = grep { looks_like_number($_) } @references;
my $total_reads  = sum @numeric_refs;
这里使用核心模块的
sum
。由于每个操作返回并获取一个列表,因此,如果只进行求和,则上述所有操作都可以放在一个语句中


更好的是,您可以使用解析以制表符分隔的文件,这可以很好地处理引号

use warnings;
use strict;
use Text::CSV;
use List::Util qw(sum);

my $csv = Text::CSV->new( 
    { binary => 1, sep_char => "\t", allow_loose_quotes => 1 } 
) or die "Cannot use CSV: " . Text::CSV->error_diag ();

my $file = $tsv_file_new;
open my $fh, '<', $file  or die "Can't open $file: $!";

while (my $row = $csv->getline($fh)) {
    my @fields = @$row;
    # process. quotes around fields are gone
    # ...
    my @references = ($forward_reference, ...);
    my $total_reads = sum grep { looks_like_number($_) } @references;
}
$csv->eof or $csv->error_diag();
close $fh;
使用警告;
严格使用;
使用Text::CSV;
使用列表::Util qw(总和);
my$csv=文本::csv->新建(
{binary=>1,sep\u char=>“\t”,允许\u loose\u quotes=>1}
)或死亡“无法使用CSV:”。Text::CSV->error_diag();
my$file=$tsv_file_new;

打开我的$fh,“您的错误消息已经显示:参数“97”不是数字。当数字实际上是一个由引号(
)包围的字符串时,就会发生这种情况,如下所示:

这使得:

参数“42”在

试着去掉数字中的引号:


97
不同,
“97”
看起来确实不像一个数字。听起来你的字段中有引号。@user3781528你确实得到了直接的答案,这很好,但我认为你应该看看这里的更新,就这样。作为替代方法-模式匹配数字组件:
my($num)=$str m/(\d+)/
@Sobrique好多了。像我一样去掉引号是一种快速的“肮脏的大锤”方法。
my $num = '"42"';
my $sum = $num + 1;
$num =~ s/"//g;