2016-06-29 2 views
2

탭으로 구분 된 파일을 구문 분석하고 있습니다. 몇몇 열은 분명히 숫자 임에도 불구하고 숫자로 인식되지 않습니다. 이러한 값을 요약하면 다음과 같은 오류가 표시됩니다. 이고 Perl은 0을 반환합니다.문자열을 숫자로 변환 "인수가 숫자 오류가 아닙니다"

나는 Scalar::Util qw(looks_like_number);을 사용해 보았지만 동일한 결과가 나오므로 '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"; 
} 
+4

' "97"'참'97'과는 달리, 숫자처럼 보이지 않는다. 당신의 들판에 따옴표가 들어있는 것 같습니다. – melpomene

답변

6

귀하의 오류 메시지가 이미 말한다.

my $num = '"42"'; 
my $sum = $num + 1; 

이 제공 : 다음 는 따옴표로 (")에 둘러싸여 실제로 문자열 ,과 같이있을 때이 문제가 발생

인수 ","42 ","아니다 또한 (+)에서 숫자 ...

시도는 숫자에서 따옴표를 제거합니다 :

$num =~ s/"//g; 
+1

다른 방법으로 숫자 구성 요소가 일치합니다.'my ($ num) = $ str = ~ m/(\ d +) /; ' – Sobrique

+0

@Sobrique 멀리 좋습니다. 내가했던 것처럼 따옴표를 벗기는 것은 quick'n'dirty 썰매 해머 접근법입니다. – PerlDuck

4


그 오류가 추가 따옴표 때문이다 (도) 끝에 추가 따옴표를 처리 할 Text::CSV를 사용하는   권장 사항 : 여기

코드입니다 하지만 먼저 코딩 문제에 대해 언급 할 것입니다. looks_like_number($var) + ...을 수행하여 값을 추가하는 것은 오류입니다. 펄은 EXPR는 숫자 생각하면 Scalar::Util에서 looks_like_number ,

true를 반환합니다.

테스트의 경우 변수가 숫자인지 여부를 나타냅니다. 0 또는 큰 양의 정수를 반환합니다. 예를 들어 grep으로 필터링하여 숫자가 무엇인지 먼저 테스트하고 그 숫자로만 사용해야합니다.

answer by perlduck에서 설명했듯이 주위에 여분의 인용 부호가 있음이 분명합니다. 그러나 실제로는 숫자가 아닌 것을 폭로 할 수 있으므로 모든 인용문을 제거하는 데주의해야합니다. 또한 다른 처리가 포함될 경우 문자열이 필요할 수도 있습니다.

마지막으로 여전히 변수를 테스트하고 looks_like_number으로 둘러싼 따옴표를 정리 한 다음 숫자를 조합합니다. 아마도

여기 sum 코어 List::Util 모듈
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; 

사용된다. 각 연산이 반환되고 목록을 취하기 때문에 합산 이외의 다른 연산이 수행되지 않으면 위의 모든 내용을 하나의 명령문에 넣을 수 있습니다.


더 나은 아직, 당신은 매우 잘 따옴표를 처리하는, Text::CSV와 탭으로 구분 된 파일을 구문 분석 할 수 있습니다. 인수 ","97 "," 숫자되지 않습니다 :

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. double 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; 
+1

@ user3781528 직접 답을 얻었는데, 좋았지 만 여기서 업데이트를 살펴 봐야한다고 생각합니다. – zdim

관련 문제