我有一个包含以下随机结构的文件:
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
答案 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