2013-05-19 114 views
1

我需要将ACARS消息解析为XML格式。ACARS消息解析

有简单的信息:(例如,[2013年5月5日9点24分])

RX_IDX: 13 
ACARS mode: O, message label: 5V 
ACARS ML description: VDL switch advisory 
Aircraft reg: .EI-EUX, flight id: UN0323 
Block id: 57, msg. no: S91A 
Message content:- 

----------------------------------------------------------[05/05/2013 08:58] 

RX_IDX: 14 
ACARS mode: 2, message label: 1L 
ACARS ML description: Off message 
Aircraft reg: .D-AIRO, flight id: LH1490 
Aircraft vendor: Airbus, short type: A321, full type: A321-131, cn: 0563 
Carrier IATA: LH, ICAO: DLH, remarks: Lufthansa 
Airlines: Lufthansa 
Block id: 56, msg. no: M03A 
Message content:- 
00002216743GO,X,55655 
----------------------------------------------------------[05/05/2013 09:24] 

每个消息与RX_IDX开始,以日期为止。

我发现perl脚本,但它不能识别逗号后的属性。

#!/usr/local/bin/perl 
use strict; 
use warnings; 

my @keys = ( 
    'RX_IDX', 
    'ACARS mode', 
    'message label', 
    'ACARS ML description', 
    'Aircraft reg', 
    'flight id', 
    'Aircraft vendor', 
    'short type', 
    'full type', 
    'cn', 
    'Carrier IATA', 
    'ICAO', 
    'remarks', 
    'Airlines', 
    'Block id', 
    'msg. no', 
    'Message content' 
); 

my(%keys, %tags); 
$keys{$_} = 1 for @keys; 
$tags{$_} = $_ . '' for @keys; 
$tags{$_} =~ s/ /_/g for @keys; 

my $file = 'data8.txt'; 
open(my $fh, '<', $file) or die("Can't open $file: $!"); 

my %record = map { $_, '' } @keys; 
while(my $line = <$fh>) { 
    chomp($line); 
    if($line =~ m{ \A (.+?) : \s* (\S+) }x) { 
     $record{$1} = $2 if $keys{$1}; 
     if($1 eq $keys[$#keys]) { 
      print "<Message>\n"; 
      print "<$tags{$_}>$record{$_}</$tags{$_}>\n" for @keys; 
      print "</Message>\n"; 
      %record = map { $_, '' } @keys; 
     } 
    } 
} 

问候

回答

0

的问题是,在正则表达式的if条件仅将每行匹配一次。尝试匹配正则表达式,直到在while循环中失败。我在下一个循环中添加了\G断言,它将在上次离开时​​开始。也改变了那么一点点,以避免在行(\A)的开头匹配,并添加在最后一个逗号的可能的匹配,这将是这样的(我复制的代码只相关部分):

while(my $line = <$fh>) { 
    chomp($line); 
    while ($line =~ m{ \G \s* (.+?) \s* : \s* ([^,]+) \s* (?:,|$) }xg) { 
     $record{$1} = $2 if $keys{$1}; 
     if($1 eq $keys[$#keys]) { 
      ... 
     } 
    } 
} 
+0

非常感谢!完美的作品。下一个问题是: - 如何匹配日期(最后一条消息行)并将其放到另一个XML属性? - 如何更改“邮件内容”?在现在仅解析器匹配 ' - ' 字符,但有时消息包含在新的生产线的一些数据,如下所示: 信息的内容: 信息的内容: - DFBOAR791#DFCPOSHL7417R391U1LILOW3073513040733 12223EB2620B C03 11 WN43507E 1833804072333398-36210 35 37630 – Pawel

+0

@Pawel:我不确定。我最初的做法可能是添加更多的if条件,一个用于以“Message content”开头的行,并将所有后面的换行符连接起来,另一个用于以多个连字符开头的行。想想看,但我会避免尝试用一个正则表达式来匹配所有内容。 – Birei