1

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

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";
}

但我总是:

;;;;;
4

4 回答 4

3

Pipe ( |) 是正则表达式中的特殊字符。逃避它,就像:\|它会工作。

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

else分支也是如此。

于 2013-03-02T21:50:23.550 回答
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;
}

不必对所有可能的键/值对及其可能的顺序进行硬编码,您可以在一段代码中对其进行一般解析。

于 2013-03-02T23:31:35.980 回答
1

改变

(.*?) 

([a-zA-Z0-9]*)
于 2013-03-02T21:46:52.457 回答
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
于 2013-03-03T14:38:06.480 回答