Perl使用正则表达式解析文本文件

时间:2013-03-02 21:38:28

标签: perl

我有一个包含以下随机结构的文件:

USMS 1362224754632|<REQ MSISDN="00966590832186" CONTRACT="580" SUBSCRIPTION="AAA" FORMAT="ascii" TEXT="L2"

USMS 1362224754632|<REQ MSISDN="00966590832186" CONTRACT="580" SUBSCRIPTION="BBB" THRESHOLDID="1" FORMAT="ascii" TEXT="L2"

我试图用perl解析它以获取如下值:

1362224754632; 00966590832186; 580; AAA; L2

以下是代码:

if($Record =~ /USMS (.*?)|<REQ MSISDN="(.*?)" CONTRACT="(.*?)" SUBSCRIPTION="(.*?)" FORMAT="(.*?)" THRESHOLDID="(.*?)" TEXT="(.*?)"/)
{
                              print LOGFILE "$1;$2;$3;$4;$5;$6;$7\n";
}
elsif($Record =~ /USMS (.*?)|<REQ MSISDN="(.*?)" CONTRACT="(.*?)" SUBSCRIPTION="(.*?)" FORMAT="(.*?)" TEXT="(.*?)"/)
{
                              print LOGFILE "$1;$2;$3;$4;$5;$6\n";
}

但我总是这样:

;;;;;

任何帮助,谢谢。 Heithem

4 个答案:

答案 0 :(得分:3)

管道(|)是正则表达式中的特殊字符。逃避它,如:\|,它将起作用。

if($Record =~ /USMS (.*?)\|<REQ MSISDN="(.*?)" CONTRACT="(.*?)" SUBSCRIPTION="(.*?)" FORMAT="(.*?)" THRESHOLDID="(.*?)" TEXT="(.*?)"/)

else分支相同。

答案 1 :(得分:3)

不是使用单个正则表达式,而是先将数据拆分为单独的部分,然后单独处理它们。

my($usms_part, $request) = split / \s* \|<REQ \s* /x, $Record;

my($usms_id) = $usms_part =~ /^USMS (\d+)$/;

my %request;
while( $request =~ /(\w+)="(.*?)"/g ) {
    $request{$1} = $2;
}

您不必硬编码所有可能的键/值对及其可能的排序,而是可以在一段代码中一般地解析它们。

答案 2 :(得分:1)

更改

(.*?) 

([a-zA-Z0-9]*)

答案 3 :(得分:0)

看起来你想要的只是双引号中包含的字段。

看起来像这样

use strict;
use warnings;

while (<DATA>) {
  my @values = /"([^"]+)"/g;
  print join(';', @values), "\n";
}

__DATA__
USMS 1362224754632|<REQ MSISDN="00966590832186" CONTRACT="580" SUBSCRIPTION="AAA" FORMAT="ascii" TEXT="L2"
USMS 1362224754632|<REQ MSISDN="00966590832186" CONTRACT="580" SUBSCRIPTION="BBB" THRESHOLDID="1" FORMAT="ascii" TEXT="L2"

<强>输出

00966590832186;580;AAA;ascii;L2
00966590832186;580;BBB;1;ascii;L2