解析输入以获取特定值

时间:2011-04-12 12:20:46

标签: regex perl

我输入的内容如下:

  

"[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;
}

也许我应该使用不同的方法。有人可以帮帮我吗?

4 个答案:

答案 0 :(得分: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}|!

  • 等部分
  • 然后解析每个部分以获取初始[

    之后的整数
  • 其余的很容易:跟踪最大的整数和相应的部分,并在最后输出。

答案 1 :(得分:0)

在shell脚本中:

#!/bin/bash                                                                     

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

第一行将大量数据切割成行,只提取第一个字段,对其进行排序并获取最大值。第二行再次将数据切割成行,并为该最大值进行grets。

如果您有大量数据,这可能会很慢,因此您可以将“已排列”的数据放入临时文件或其他内容。

答案 2 :(得分:0)

当您知道要丢弃的内容时,

split()是正确的工具。当您知道要保留的内容时,捕获或m // g是正确的工具。 (从兰德尔施瓦茨的话引用)。

你想指定要保留的内容(方括号之间)而不是扔掉的东西(没有!)。

幸运的是,您的数据是“哈希形状”(即交替的键和值),因此将其加载到哈希中,对键进行排序,并输出最高键的值:

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";

答案 3 :(得分: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]
相关问题