2013-08-12 3 views
1
나는이 샘플 데이터에서 분리 된 두 개의 숫자 비교하려는

:정규식 값 비교

#!/usr/bin/perl -w 
use strict; 
use File::Slurp; 
use Data::Dumper; 
$Data::Dumper::Sortkeys = 1; 

my (@log_change, @largest_change); 
     foreach (@intersect) { 
      chomp; 
      my @condition1_match = ($_ =~ /C1:.*?Change:(-?\d+\.\d+)|C1:.*?Change:(-?inf)/); # Sometimes the value is 'inf' or '-inf'. This allows either a numerical or inf value to be captured. 
      my @condition2_match = ($_ =~ /C2:.*?Change:(-?\d+\.\d+)|C2:.*?Change:(-?inf)/); 
      push @log_change, "@condition1_match\[email protected]_match"; 
     } 

    print Dumper (\@log_change); 

이 출력 제공 : 이상적으로

  '1.3118 2.07985 ', 
      '1.18887 0.990066 ', 
      '2.63964 2.31757 ', 

을 다음 정규식을 사용하여

'gi|112807938|emb|CU075707.1|_Xenopus_tropicalis_finished_cDNA,_clone_TNeu129d01 C1:TCONS_00039972(XLOC_025068),_12.9045:32.0354,_Change:1.3118,_p:0.00025,_q:0.50752 C2:TCONS_00045925(XLOC_029835),_10.3694:43.8379,_Change:2.07985,_p:0.0004,_q:0.333824', 
'gi|115528274|gb|BC124894.1|_Xenopus_laevis_islet-1,_mRNA_(cDNA_clone_MGC:154537_IMAGE:8320777),_complete_cds C1:TCONS_00080221(XLOC_049570),_17.9027:40.8136,_Change:1.18887,_p:0.00535,_q:0.998852 C2:TCONS_00092192(XLOC_059015),_17.8995:35.5534,_Change:0.990066,_p:0.0355,_q:0.998513', 
'gi|118404233|ref|NM_001078963.1|_Xenopus_(Silurana)_tropicalis_pancreatic_lipase-related_protein_2_(pnliprp2),_mRNA C1:TCONS_00031955(XLOC_019851),_0.944706:5.88717,_Change:2.63964,_p:0.01915,_q:0.998852 C2:TCONS_00036655(XLOC_023660),_2.31819:11.556,_Change:2.31757,_p:0.0358,_q:0.998513', 

을 같은 루프 내에서 @condition1_match과에있는 값을 비교하기를 원합니다.은 더 큰 값이 숫자가 아닌 'inf'와 비교되지 않는 한 새로운 배열로 푸시됩니다. 이 같은

뭔가 :

my (@log_change, @largest_change); 
     foreach (@intersect) { 
      chomp; 
      my @condition1_match = ($_ =~ /C1:.*?Change:(-?\d+\.\d+)|C1:.*?Change:(-?inf)/); 
      my @condition2_match = ($_ =~ /C2:.*?Change:(-?\d+\.\d+)|C2:.*?Change:(-?inf)/); 
      push @log_change, "@condition1_match\[email protected]_match"; 
       unless ($_ =~ /Change:-?inf/) { 
        if (@condition1_match > @condition2_match) { 
         push @largest_change, @condition1_match; 
        } 
        else { 
         push @largest_change, @condition2_match; 
        } 

       } 

     } 

    print Dumper (\@largest_change); 

제공 :

  '2.07985', 
      undef, 
      '0.990066', 
      undef, 
      '2.31757', 
      undef, 

을뿐만 아니라,이 오류 메시지의 많은 같이

Use of uninitialized value $condition2_match[1] in join or string at intersect.11.8.pl line 114. 

나는에 관해서는 확실 해요 정확히 오류 메시지 의미뿐만 아니라 내에서 undef 값을 얻고있다 @largest_change

답변

2

코드를 작성한대로 @condition_match1@condition_match2은 일치하는 항목이있을 때마다 정규 표현식의 2 개의 캡처 그룹에 해당하는 2 개의 요소가 만들어집니다. 그러나이 요소 중 하나는 반드시 undef이어야하며 uninitialized ... 경고가됩니다. 이 경우

, 당신은 캡처 그룹 내부의 |를 넣어이 프로그램을 복구 할 수 있습니다 :

my ($condition1_match) = ($_ =~ /C1:.*?Change:(-?\d+\.\d+|-?inf)/); 
my ($condition2_match) = ($_ =~ /C2:.*?Change:(-?\d+\.\d+|-?inf)/); 

이 하나의 캡처 그룹과 일치하는 작업이 하나의 정의 된 요소 목록을 생성하도록 . 또한

, 비교

if (@condition1_match > @condition2_match) { 

은 아마 당신이하고있는 생각하고 있지 않습니다. Perl에서 두 배열 간의 수치 비교는 배열 길이의 비교입니다. 답장을

my $condition1_match = $condition1_match[0] // $condition1_match[1]; 
my $condition2_match = $condition2_match[0] // $condition2_match[1]; 
if ($condition1_match > $condition2_match) { 
    push @largest_change, $condition1_match; 
} else { 
    push @largest_change, $condition2_match; 
} 
+0

감사합니다 : 당신이 분명히 할 말은 당신 같은 더 성가신 일을 할 필요가 있으므로, 그 배열의 각에 정의 된 값을 비교하는 것입니다. '@array'> '@array'가 작동하지 않는다는 사실을 알지 못했던 정말로 나를 빽빽하게 - 대답의 두 번째 부분에 대해 자세히 설명해 주실 수 있습니까? – fugu

+0

마찬가지로 왜 각 배열에는 두 개의 정의 된 값이 있습니까? 왜 각 배열의 요소 [0]과 [1]을 비교합니까? – fugu

+0

정규 표현식은 하나의 일치를 생성 할 수 있기 때문에 각 배열에 정의 된 값이 하나 있습니다 :'/ ($ expr1) | ($ expr2) /'는'$ 1 '에'$ expr1'을 할당합니다 if '$ expr1'은 일치합니다. 그렇지 않으면'$ expr2'가 일치하면'$ expr2'를'$ 2'에 할당합니다. '$ a = $ b // $ c'는'$ a = defined ($ b)? $ b : $ c', 즉'$ b'가 정의되어 있다면'$ b'를, 그렇지 않으면'$ c'를 대입합니다. – mob