how to find the lengh of the input in an array and match pattern in perl

前端 未结 2 1476
南旧
南旧 2020-12-22 13:46

i am new to to the perl scripting i have an array like this my @array (0x0B,0x04,0x02767,0x0000,0xffffaf) my expected output: if the length of the index is more

2条回答
  •  臣服心动
    2020-12-22 14:47

    Sounds like you have a bunch of 32-bit values as hex, and that you want to pack them into the specified big-endian type, and that you want a hex representation of the packed structure.

    (Note that this assumes you are wrong about the output for gtotal. If I understand correctly, 0xffffffaf means -81, which is 0xAF as a Sint8.)

    use strict;
    use warnings;
    use feature qw( say );
    
    my %packers = (
       Uint8  => sub { pack 'C*',  @_ },
       Sint8  => sub { pack 'c*',  @_ },
       Uint16 => sub { pack 'S>*', @_ },
       Sint16 => sub { pack 's>*', @_ },
       Uint32 => sub { pack 'L>*', @_ },
       Sint32 => sub { pack 'l>*', @_ },
    );
    
    my $packed = '';
    
    while () {
       my ($vals, $type);
       if (/^\S+ \s+ \{ \s* ( 0x[0-9a-fA-F]+ (?: \s* , \s* 0x[0-9a-fA-F]+ )* ) \s* \} \s+ ([^\s,]+) /x) {
          $vals = $1;
          $type = $2;
       }
       elsif (/^\S+ \s+ ( 0x[0-9a-fA-F]+ )\s+ ([^\s,]+) /x) {
          $vals = $1;
          $type = $2;
       }
       else {
          die("Unrecognized syntax at line $.\n");
       }
    
       my @vals =
           map { unpack 'l', pack 'l', hex $_ }  # Convert to number and fix the sign
              split /\s*,\s*/,
                 $vals;
    
       my $packer = $packers{$type}
          or die("Unsupported type \"$type\"\n");
    
       $packed .= $packer->(@vals);
    }
    
    # say sprintf '%v02X', $packed;
    
    say
       join ',',
          map { sprintf("0x%02X", $_) }
             unpack 'C*',
                $packed;
    
    __DATA__
    total_sum   0x0B    Uint8,unsigned char
    num     0x0C    Uint8,unsigned char
    max     0x4A    Uint8,unsigned char
    padd    0x00     Uint8,unsigned char
    ideal   0x01    Uint16, unsigned short
    newtext{2}  { 0x00, 0x00 }  Uint8,unsigned char
    my_new  0x02     Uint16, unsigned short
    newtest2{2} { 0x00, 0x00 }  Uint8,unsigned char
    xyz         0x0A     Uint8,unsigned char
    newtest4{3} { 0x00, 0x00, 0x00 }    Uint8,unsigned char
    gtotal 0xffffffaf   Sint8,signed char
    info    0x2767  Uint16, unsigned short
    

    Output:

    0x0B,0x0C,0x4A,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x0A,0x00,0x00,0x00,0xAF,0x27,0x67
    

提交回复
热议问题