如何匹配统一的HTML表?

时间:2011-08-21 22:58:03

标签: regex

我对这个正则表达式很失落。我有一个包含3个字段的HTML表格:日期,名称和地点。表的第一个记录没有字段“Place”(我无法更改表格格式)...目前我正在使用下面的模式:

^<tr><td.*>(.+)<\/td><td>(.+)<\/td><td><font.*>(.+)<\/font><\/td><\/tr> $\n<tr><td.*>(.+)<\/td><\/tr>

此模式忽略表的第一条记录(此记录没有字段“Place”)。我不想为同一文本创建2个模式。有人可以帮忙解决这个问题吗?

表格样本:

<table  border cellpadding=1 hspace=10> 
<colgroup style='font:8pt Tahoma;color=Black' valign=top><colgroup style='font:8pt Tahoma; color=Navy'><colgroup style='font:8pt Tahoma;color=Maroon'> 
<tr> 
<td><font FACE=Tahoma color='#CC0000' size=2><b>Date</b></font></td> 
<td><font FACE=Tahoma color='#CC0000' size=2><b>Name</b></font></td> 
<td><font FACE=Tahoma color='#CC0000' size=2><b>Place</b></font></td> 
</tr> 
<tr><td rowspan=2>17/08/2011 10:28</td><td>Vivamus sed est ut lorem tempor cursus</td><td><FONT COLOR="000000">Curabitur egestas metus bibendum</font></td></tr> 
<tr><td colspan=2>Curabitur id urna elit</td></tr> 
<tr><td rowspan=2>17/08/2011 10:26</td><td>UDonec blandit nisl ut nisl elementum</td><td><FONT COLOR="000000"> hendrerit vel ante</font></td></tr> 
<tr><td colspan=2>Etiam nec mollis</td></tr> 
<tr><td rowspan=2>12/08/2011 09:46</td><td>Nulla et eros a massa</td><td><FONT COLOR="000000">Aenean in mauris eget tellus </font></td></tr> 
<tr><td colspan=2>Nulla et eros a massa tristique blandit </td></tr> 
<tr><td rowspan=2>12/08/2011 09:45</td><td>orta mi dapibus sit amet. Vestib</td><td><FONT COLOR="000000"> mollis erat consectetur.</font></td></tr> 
<tr><td colspan=2>sodales tempor</td></tr> 
<tr><td rowspan=1>11/08/2011 10:39</td><td>lorem ipsum</td><td><FONT COLOR="000000">dolor</font></td></tr>
</TABLE> 

目前的解决方案是创建2个正则表达式。 没有第一个记录的第一个正则表达式捕获表:

^<tr><td.*>(.+)<\/td><td>(.+)<\/td><td><font.*>(.+)<\/font><\/td><\/tr> $\n<tr><td.*>(.+)<\/td><\/tr>

第二个正则表达式捕获第一个记录:

^<tr><td.*>(.+)<\/td><td>(.+)<\/td><td><font.*>(.+)<\/font><\/td><\/tr> $

3 个答案:

答案 0 :(得分:1)

更正式地说,XML和相关语言不是常规语言,这就是它们不适合通过正则表达式进行解析的原因。如果没有编写自己的递归下降解析器,最好的办法是使用现有的解决方案。

答案 1 :(得分:1)

因为这是一个很容易解决的问题,所以不需要任何困难。你缺少的是你需要使用最小匹配量词而不是最大匹配量词。由于font vs FONT,您还需要案例折叠。

这是一个简单的演示,它适用于您的强制/固定/固定数据集:

#!/usr/bin/env perl

while (<DATA>) {
    print "FONT='$1' CONTENTS='$2'\n" while m{
        <td [^<>]*? >
            <font \s+ ([^<>]*?) >
                ( .*? )
            </font>
        </td>
    }gsix;
}
__END__
<table  border cellpadding=1 hspace=10>
<colgroup style='font:8pt Tahoma;color=Black' valign=top><colgroup style='font:8pt Tahoma; color=Navy'><colgroup style='fon
t:8pt Tahoma;color=Maroon'>
<tr>
<td><font FACE=Tahoma color='#CC0000' size=2><b>Date</b></font></td>
<td><font FACE=Tahoma color='#CC0000' size=2><b>Name</b></font></td>
<td><font FACE=Tahoma color='#CC0000' size=2><b>Place</b></font></td>
</tr>
<tr><td rowspan=2>17/08/2011 10:28</td><td>Vivamus sed est ut lorem tempor cursus</td><td><FONT COLOR="000000">Curabitur eg
estas metus bibendum</font></td></tr>
<tr><td colspan=2>Curabitur id urna elit</td></tr>
<tr><td rowspan=2>17/08/2011 10:26</td><td>UDonec blandit nisl ut nisl elementum</td><td><FONT COLOR="000000"> hendrerit ve
l ante</font></td></tr>
<tr><td colspan=2>Etiam nec mollis</td></tr>
<tr><td rowspan=2>12/08/2011 09:46</td><td>Nulla et eros a massa</td><td><FONT COLOR="000000">Aenean in mauris eget tellus
</font></td></tr>
<tr><td colspan=2>Nulla et eros a massa tristique blandit </td></tr>
<tr><td rowspan=2>12/08/2011 09:45</td><td>orta mi dapibus sit amet. Vestib</td><td><FONT COLOR="000000"> mollis erat conse
ctetur.</font></td></tr>
<tr><td colspan=2>sodales tempor</td></tr>
<tr><td rowspan=1>11/08/2011 10:39</td><td>lorem ipsum</td><td><FONT COLOR="000000">dolor</font></td></tr>
</TABLE>

运行时会生成此输出:

FONT='FACE=Tahoma color='#CC0000' size=2' CONTENTS='<b>Date</b>'
FONT='FACE=Tahoma color='#CC0000' size=2' CONTENTS='<b>Name</b>'
FONT='FACE=Tahoma color='#CC0000' size=2' CONTENTS='<b>Place</b>'
FONT='COLOR="000000"' CONTENTS='Curabitur egestas metus bibendum'
FONT='COLOR="000000"' CONTENTS=' hendrerit vel ante'
FONT='COLOR="000000"' CONTENTS='Aenean in mauris eget tellus '
FONT='COLOR="000000"' CONTENTS=' mollis erat consectetur.'
FONT='COLOR="000000"' CONTENTS='dolor'

一般来说,你希望一次把这些东西拉出来。

首先正确生成它会更好,但是一个人必须做到这一点。

那么,你有任何问题吗? :)

当然,有一百万件事情无法处理,但那又如何呢?

  • 首先,如果我来处理这些事情中的任何一件事,I very most certainly can.
  • 但更重要的是,在明确定义的HTML中,这些步骤不是必需的,这意味着像这样的简单模式非常好。

当你不需要它时,不要陷入过度设计一百万美元解决方案的陷阱。

答案 2 :(得分:0)

只有一个正确的答案。不要使用正则表达式来解析HTML。只是不要。甚至不要考虑它。它会给你带来痛苦。