编写此正则表达式以匹配多顺序属性列表的更好方法是什么?

时间:2010-04-11 22:53:52

标签: regex perl multiple-matches

我一直在打破这个正则表达式,尝试构建一些可以从.ics文件中选择多个有序属性值(DTSTART,DTEND,SUMMARY)的东西。我有其他选择(比如一次读一行和扫描),但是想构建一个可以处理整个事情的正则表达式。

样本PERL

# There has got to be a better way...
my $x1 = '(?:^DTSTART[^\:]*:(?<dts>.*?)$)';
my $x2 = '(?:^DTEND[^\:]*:(?<dte>.*?)$)';
my $x3 = '(?:^SUMMARY[^\:]*:(?<dtn>.*?)$)';
my $fmt = "$x1.*$x2.*$x3|$x1.*$x3.*$x2|$x2.*$x1.*$x3|$x2.*$x3.*$x1|$x3.*$x1.*$x2|$x3.*$x2.*$x1";

if ($evts[1] =~ /$fmt/smo) {
printf "lines:\n==>\n%s\n==>\n%s\n==>\n%s\n", $+{dts}, $+{dte}, $+{dtn};
} else {
print "Failed.\n";
}

样本数据

BEGIN:VEVENT
UID:0A5ECBC3-CAFB-4CCE-91E3-247DF6C6652A
TRANSP:不透明
摘要:Gandalf_flinger1
DTEND:20071127T170005
DTSTART,朗= EN_US:20071127T103000
DTSTAMP:20100325T003424Z
X-APPLE-EWS-BUSYSTATUS:BUSY
顺序:0
结束:VEVENT

SAMPLE OUTPUT

行:
==&GT;
20071127T103000
==&GT;
20071127T170005
==&GT;
Gandalf_flinger1

4 个答案:

答案 0 :(得分:2)

CPAN是你的朋友:

vFile

iCal parser

你将把你的头发拉出来,直到秃头没有vFile格式的解析器(除了普通的文件。)正则表达非常困难。

答案 1 :(得分:1)

为什么不分别测试三个模式,为什么不分别测试三个模式,因为(给定锚定$ s)它们不能重叠?

my $x1 = qr/(?:^DTSTART[^:]*:(?<dts>.*?)$)/smo;
my $x2 = qr/(?:^DTEND[^:]*:(?<dte>.*?)$)/smo;
my $x3 = qr/(?:^SUMMARY[^:]*:(?<dtn>.*?)$)/smo;

if ($evts[1] =~ $x1 and $evts[1] =~ $x2 and $evts[1] =~ $x3)
{
    # ...
}

(我还将x变量自身转换为模式,并删除了字符类中不需要的转义。)

答案 2 :(得分:0)

最好使用三个正则表达式和一些额外的逻辑。这个问题与正则表达式不太匹配。

答案 3 :(得分:0)

那很丑......我认为“更好的方法”是每次匹配每个属性。