2012-05-25 23 views
2

我有一個XML文件,我需要使用Perl將其傳遞到列表(不使用XSLT)。Perl使用困難正則表達式從XML寫入字符串

這是我的(simplyfied,像10多個屬性去掉,使其更容易閱讀!)XML:

... 
<XMLTAG ID="1" name="NAME1" status="0" date1="24.05.2012 13:37:00" date2="25.05.2012 13:37:00" /> 
<XMLTAG ID="2" name="NAME2" status="1" date1="24.05.2012 13:37:00" date2="25.05.2012 13:37:00" /> 
<XMLTAG ID="3" name="NAME3" status="0" date1="24.05.2012 13:37:00" date2="25.05.2012 13:37:00" /> 
... 

我走到這一步:

my $input = in.xml; 
my $output = out.txt; 

# open input 
open(INPUT, $input) 
    || die "Can't find $input: $_"; 

# open output 
open(OUTPUT, ">$output") 
    || die "Can't find $output: $_"; 

    # run until perl returns undef (at the end of the file) 
    while (<INPUT>) { 
     if ($_ == /date1=\"[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2} [0-5][0-9]:[0-5][0-9]:[0-5][0-9]\"/) { 
     print OUTPUT $_;}; 
    } 
    close(INPUT); 
    close(OUTPUT); 

輸出文件應該是像這樣:

date1="24.05.2012 13:37:00" 
date1="24.05.2012 13:37:01" 
date1="24.05.2012 13:37:02" 
... 

由於提前, 馬利

+1

讓我給你一個代碼,t這裏有一個很好的正則表達式在45行匹配的名字。你應該明確匹配名稱以獲得更好的可讀性:https://github.com/seckin206/Log2KML-Parser/blob/master/logviewer.pl –

+0

** if( m#date1 =「([^」] +)#){print「date1 = $ 1」; } ** – tuxuday

+3

永遠不要使用正則表達式解析XML/HTML/CSV文件。使用現有的模塊,它們通常是成熟的,穩定的並且經過良好測試。 – dgw

回答

6
use XML::LibXML qw(); 
my $dom = XML::LibXML->load_xml(location => 'in.xml'); 
printf qq(date1="%s"\n), $_->getAttribute('date1') 
    for $dom->findnodes('//XMLTAG'); 
+1

+1,但是你的困難正則表達式在哪裏?) – flesk

+0

非常感謝!) – Marley

0

嘗試:

date1=\"(.*?)\" 

爲您正則表達式,它會使非貪婪搜索。

UPDATE:

他們警告我說,沒有必要轉義雙引號,所以

date1="(.*?)" 

會做。

+2

有沒有必要逃避雙引號 – Borodin

+0

我不在這裏有一個perl解釋器,所以我無法驗證你的評論,我的朋友 –

+0

yep escape is not redd – tuxuday

1

您應該使用正確的XML解析模塊。有很多可用的,但這裏是使用XML::Smart的解決方案。

這不是我會選擇的解決方案,但我有興趣知道爲什麼您已經註銷了XSLT?

use strict; 
use warnings; 

use XML::Smart; 

my $input = 'in.xml'; 
my $output = 'out.txt'; 

open my $out, '>', $output or die qq(Can't open output file "$output": $!); 

my $xml = XML::Smart->new($input); 
my $text = $xml->{root}{XMLTAG}; 

my $xmltags = $xml->{root}{XMLTAG}; 

for my $tag (@$xmltags) { 
    print $out qq(date1="$tag->{date1}"\n); 
} 

輸出

date1="24.05.2012 13:37:00" 
date1="24.05.2012 13:37:00" 
date1="24.05.2012 13:37:00" 
0

您可以使用一個非貪婪的比賽,就像這樣:

if ($_ =~ /(date1=".*?")/) { 
     print OUTPUT "$1\n"; 
    }