2011-04-12 68 views
1

我輸入這樣的:解析輸入來獲得特定值

"[0|0|{A=145,B=2,C=12,D=18}|!][0|0|{A=167,B=2,C=67,D=17}|.1iit][196|0|{A=244,B=6,C=67,D=12}|10:48AM][204|0|{A=9,B=201,C=61,D=11}|Calculator][66|0|{A=145,B=450,C=49,D=14}|phone]0|0|{A=145,B=2,C=12,D=18}|!0|0|{A=167,B=2,C=67,D=17}|.1iit196|0|{A=244,B=6,C=67,D=12}|10:48AM204|0|{A=9,B=201,C=61,D=11}|Calculator66|0|{A=145,B=450,C=49,D=14}|phone";

它顯示爲一條連續的線,沒有換行。我需要在[和第一個出現的 |之間的值中的最大值 。例如,在這種情況下,最大值是204。一旦獲得 ,我想打印[]之間的元素 的內容。在這種情況下,它將是「204 | 0 | {A = 9,B = 201,C = 61,D = 11} |計算器」。

我已經試過這樣的事情,但它不會去任何地方:

my @array1; 

my $data = "[0|0|{A=145,B=2,C=12,D=18}|!][0|0|{A=167,B=2,C=67,D=1 
+7}|.1iit][196|0|{A=244,B=6,C=67,D=12}|10:48AM][204|0|{A=9,B=201,C=61, 
+D=11}|Calculator][66|0|{A=145,B=450,C=49,D=14}|phone]0|0|{A=145,B=2,C 
+=12,D=18}|!0|0|{A=167,B=2,C=67,D=17}|.1iit196|0|{A=244,B=6,C=67,D=12} 
+|10:48AM204|0|{A=9,B=201,C=61,D=11}|Calculator66|0|{A=145,B=450,C=49, 
+D=14}|phone"; 

my $high = 0; 
my @values = split(/\[([^\]]+)\]/,$data) ; 
print "Values is @values \n"; 

foreach (@values) { 
    # I want the value that preceeds the first occurence of | in each array 
    # element, i.e. 0,0,196,204, etc. 
    my ($conf,$rest)= split(/\|/,$_); 
    print "Conf is $conf \n"; 
    print "Rest is $rest \n"; 
    push(@array1, $conf); 
    push (@array2, $rest); 
    print "Array 1 is @array1 \n"; 
    print "Array 2 is @array2 \n"; 
} 

$conf = highest(@array1); 
my $i=0; 

# I want the index value of the element that contains the highest conf value, 
# in this case 204. 

for (@myarray1) { last if $conf eq $_; $i++; }; 
print "$conf=$i\n"; 

# I want to print the rest of the string that was split in the same index 
# position. 

$rest = @array2[$i]; 
print "Rest is $rest \n"; 

# To get the highest conf value 

sub highest { 
    my @data = @_; 
    my $high = 0; 
    for(@data) { 
     $high = $_ if $_ > $high; 
    } 
    $high; 
} 

也許我應該使用不同的方法。請有人幫助我嗎?

回答

1

方式一:

#!/usr/bin/perl 

use strict; 

my $s = "[0|0|{A=145,B=2,C=12,D=18}|!][0|0|{A=167,B=2,C=67,D=17}|.1iit][196|0|{A=244,B=6,C=67,D=12}|10:48AM][204|0|{A=9,B=201,C=61,D=11}|Calculator][66|0|{A=145,B=450,C=49,D=14}|phone]"; 

my @parts = split(/\]/, $s); 

my $max = 0; 
my $data = ""; 
foreach my $part (@parts) { 
    if ($part =~ /\[(\d+)/) { 
     if ($1 > $max) { 
      $max = $1; 
      $data = substr($part, 1); 
     } 
    } 
} 
print $data."\n"; 

有兩點要注意:

  • 您可以通過\]分割你的原始字符串,讓你獲得部件,如[0|0|{A=145,B=2,C=12,D=18}|!

  • 然後您解析每個部分以獲得初始後的整數[

  • 剩下的很簡單:跟蹤最大的整數和相應的部分,並在最後輸出它。

+0

對不起,response..was病了,而遲到。這代碼工作般的魅力....感謝這麼多.. – MarsMax 2011-04-19 10:45:56

+0

不客氣:) – MarcoS 2011-04-21 06:09:20

+0

嗨marcoS ..雖然這個代碼工程完美時,有整數..最大返回完美..但如果有像[0.98736 | 0 | {A = 145,B = 2, C = 12,d = 18} |!] [0.67826 | 0 | {A = 167,B = 2,C = 67,d = 17} | .1iit] [0.76543 | 0 | {A = 244,B = 6 ,C = 67,d = 12} | 10:48AM] [0.7775 | 0 | {A = 9,B = 201,C = 61,d = 11} |計算器] [0.999 | 0 | {A = 145,B = 450,C = 49,D = 14} |電話]「..在這種情況下我沒有得到正確的值.. – MarsMax 2011-04-23 07:04:22

0

在shell腳本:

#!/bin/bash                  

MAXVAL=$(cat /tmp/data | tr [ "\\n" | cut -d"|" -f1 | sort -n | tail -1) 
cat /tmp/data | tr [] "\\n" | grep ^$MAXVAL 

第一線切割線數據的質量大到線,提取僅僅是第一場,排序,並採取最大。第二行再次將數據切分爲多行,並針對該最大值進行查詢。

如果你有很多的數據,這可能會很慢,所以你可以把「線」數據放入臨時文件或其他東西。這樣做的

0

split()是正確的工具,當你知道你想扔掉什麼。當你知道你想要保留什麼時,捕獲或m // g是正確的工具。 (從Randal Schwartz的報價轉述)。

你想指定要保留(方括號之間)什麼,而不是丟棄什麼(沒有!)。

幸運的是,你的數據是「散列形」(即交替的鍵和值。),所以它裝入一個散列,鍵進行排序,並輸出爲最高鍵的值:

my %data = $data =~ /\[ 
         (\d+)  # digits are the keys 
         ([^]]+) # rest are the values 
        \]/gx; 
my($highest) = sort {$b <=> $a} keys %data; # inefficent if $data is big 
print $highest, $data{$highest}, "\n"; 
0

另一個這樣做的方式:

#!/usr/bin/perl 

use strict; 

my $str = '[0|0|{A=145,B=2,C=12,D=18}|!][0|0|{A=167,B=2,C=67,D=17}|.1iit][196|0|{A=244,B=6,C=67,D=12}|10:48AM][204|0|{A=9,B=201,C=61,D=11}|Calculator][66|0|{A=145,B=450,C=49,D=14}|phone]0|0|{A=145,B=2,C=12,D=18}|!0|0|{A=167,B=2,C=67,D=17}|.1iit196|0|{A=244,B=6,C=67,D=12}|10:48AM204|0|{A=9,B=201,C=61,D=11}|Calculator66|0|{A=145,B=450,C=49,D=14}|phone'; 

my $maxval = 0; 
my $pattern; 
while ($str =~ /(\[(\d+)\|.+?\])/g) 
{ 
     if ($maxval < $2) { 
       $maxval = $2; 
       $pattern = $1; 
     } 
} 

print "Maximum value = $maxval and the associate pattern = $pattern \n"; 
# In this example $maxvalue = 204 
# and $pattern = [204|0|{A=9,B=201,C=61,D=11}|Calculator] 
+0

對不起,遲到的迴應..我生病了一段時間,這段代碼最初工作..但是發生了什麼事情,所有的時間,最大值沒有得到回報,有時第一個值得到返回。 MarcOs正常工作..無論如何非常感謝.. – MarsMax 2011-04-19 10:44:11