我希望Perl中的代码能够拆分带有多个分隔符的字符串

时间:2016-07-17 04:07:18

标签: regex perl

我有一个这样的字符串:

LOADID##49945-19-0-3540FAA-16995-16995%%ANAME##NWADVE15%%AID##51826%%AGNAME##ADDLEXPR%%AGID##49945%%HNAME##teranetcmoduat.teraner.com%%LOADDATE##07-12-16%%LOADTIME##02-04-53.end

我必须提取参数的值:

LOADID, ANAME, AID, AGNAME, AGID, HNAME, LOADDATE, LOADTIME

...并将其写入文本文件。输出格式为:

49945-19-0-3540FAA-16995-16995|NWADVE15|51826|ADDLEXPR|49945|teranetcmoduat.teraner.com|07-12-16|02-04-53

3 个答案:

答案 0 :(得分:1)

解析

my %rec = split /##|%%/, $s, -1;

-OR -

my %rec = map { split /##/, $_, 2 } split /%%/, $s;

后者的优点是它支持没有值的键,以及包含##的值。简单地说,它更可靠。

打印

my @headers = qw( LOADID ANAME AID AGNAME AGID HNAME LOADDATE LOADTIME );

say join "|", @rec{@headers};

-OR -

use Text::CSV_XS qw( );

my @headers = qw( LOADID ANAME AID AGNAME AGID HNAME LOADDATE LOADTIME );

my $csv = Text::CSV_XS->new({
   auto_diag => 2,
   binary    => 1,
   sep_char  => '|',
});

$csv->say(\*STDOUT, [ @rec{@headers} ]);

后者生成以管道分隔的CSV文件,因此它可以支持包含|的值,但可以使用CSV引用。

答案 1 :(得分:-1)

根据您的输入,您可以搜索

^LOADID##([^%]+)%%ANAME##([^%]+)%%AID##([^%]+)%%AGNAME##([^%]+)%%AGID##([^%]+)%%HNAME##([^%]+)%%LOADDATE##([^%]+)%%LOADTIME##([^%]+).end$

并替换为

\1|\2|\3|\4|\5|\6|\7|\8

有:

  • 查找固定部件,并捕获参数值
  • 假设“没有空参数值”(可以根据需要在搜索表达式中用+替换*。)和
  • 如果任何参数值可能包含百分号,则
  • 将失败。

查看实际操作:RegEx101

但字符串拆分可能更有效。

请评论是否需要调整/进一步详细说明。

答案 2 :(得分:-1)

只需一个带有2个正则表达式替换的简单Perl脚本即可 (用Perl 5测试)

$ cat input.txt
LOADID##49945-19-0-3540FAA-16995-16995%%ANAME##NWADVE15%%AID##51826%%AGNAME##ADDLEXPR%%AGID##49945%%HNAME##teranetcmoduat.teraner.com%%LOADDATE##07-12-16%%LOADTIME##02-04-53.end

$ echo 's/(.*?)##(.*?)(?:%%|\.end$|$)/$2|/g;s/\|$//' > pipeitup.pl

$ perl -p pipeitup.pl input.txt > result.txt

$ cat result.txt
49945-19-0-3540FAA-16995-16995|NWADVE15|51826|ADDLEXPR|49945|teranetcmoduat.teraner.com|07-12-16|02-04-53

添加第二个正则表达式替换s/\|$//以删除管道末尾 因此,如果最终的管道不会给您带来麻烦,那么您可以将其高尔夫球化为只有第一个正则表达式替换s/(.*?)##(.*?)(?:%%|\.end$|$)/$2|/g

顺便说一句,只需稍作修改即可打印带有字段名称的标题。 (因为这些名称在第一个正则表达式的捕获组1中)

$ head -n1 input.txt |perl -p -e 's/(.*?)##(.*?)(?:%%|\.end$|$)/$1|/g;s/\|$//' >header.txt