perl对文本具有强大的处理能力。对于xml的处理,perl自带有XML::DOM 和 XML::Simple两个模块用来处理XML。
XML::DOM过于庞大,而且解析结果是一个DOM树,操作也不方便。我们更多的是处理小型简单的XML文件,所以更多的是采用XML::Simple。
但不管是DOM还是Simple,当涉及到gb2312和GBK编码的时候,虽然对perl用encodeing = "GB2312 " 指定编码,但由于一些火星文,
还是常常解析出错。而且用这两个模块处理的时候,一旦出错,就导致整个文件不能解析。
对于特定的场合,完全可以用perl的正则匹配语法,来处理xml文件。
比如下面的文本
<m>
<c> 今日特价 【QQ商城千件秒杀】百事运动 防震缓冲慢跑男鞋 翼神 </c>
<i>0</i>
<y>0</y>
<t>20100605065101</t>
<k>250470602</k>
</m>
<m>
<c>我想今天买这双鞋</c>
<i>0</i>
<y>0</y>
<t>20100605065125</t>
<k>250470602</k>
</m>
首先,通过下面函数,将每一个消息隔开。注意其中消息可能换行的处理。
sub processmessages
{
my $processmessages = $_[0];
if($processmessages =~ /<message>(.*)<//message>/)
{
my $msgcont = $1;
while( $msgcont =~ /<m>(.*?)<//m>(.*)/ )
{
my $onemesg = $1;
#print "#########################/n";
&processonemsg($onemesg);
#print "/n########################/n";
}
}
}
然后对每条消息进行处理
sub processonemsg
{
my $mesg = $1;
if ($mesg =~ /<c>(.*)<i>(.*)<y>(.*)<//y><t>(.*)<//t><k>(.*)<//k>/)
{
print ResultFile $caseid;
print ResultFile "/t";
print ResultFile $bossid;
print ResultFile "/t";
print ResultFile $casestarttime;
print ResultFile "/t";
print ResultFile $caseendtime;
print ResultFile "/t";
print ResultFile $3;
print ResultFile "/t";
print ResultFile $4;
print ResultFile "/t";
print ResultFile $5;
print ResultFile "/t";
print ResultFile $1;
print ResultFile "/n";
}
}
这样,完全规避了对其中非ascii编码的处理。不管什么编码格式,都可以处理。
一旦有个别消息不能处理,丢弃的只是个别消息,而不会影响整个文件的处理。