在previous question中,我提出了多种匹配模式。现在我的问题是:
我有一些匹配的模式:
$text =~ m#finance(.*?)end#s;
(1)
$text =~ m#<class>(.*?)</class>#s;
(2)
$text =~ m#/data(.*?)<end>#s;
(3)
$text =~ m#/begin(.*?)</begin>#s;
(4)
我想首先匹配(1),(2)和(3)。但是, 匹配后(1)或(2),如果(4)在另一个之前出现(1)或(2),然后不匹配(3)但仅匹配(4)。所以基本上(4)的外观不包括(3)匹配。但是在没有(4)出现的情况下,(3)匹配。有没有好办法呢?
非常感谢。
答案 0 :(得分:1)
你的规范中有一个不明确的地方:仅仅从匹配(4)到匹配(1)/(2)抑制(3),或者范围更广?
在任何情况下,最好用状态机解决这个问题。
my $state = 0;
while ($text =~ m#(?: finance (.*?) end
| <class> (.*?) </class>
| data (.*?) </end>
| begin (.*?) </begin>
)
#sgx) {
if (defined $1) {
$state = ($state & ~4) | 1;
print $1;
}
elsif (defined $2) {
$state = ($state & ~4) | 2;
print $2;
}
elsif (defined $3 and !($state & 4)) {
print $3;
}
elsif (defined $4) {
print $4;
if ($state & 3) { # 1 OR 2
$state = 4; # set 4, clear 1 and 2
}
}
else {
die 'Someone modified me without extending the state machine!';
}
}
(这是语法检查,但没有经过测试;它足够复杂,样本数据集很有用。)