1

我正在从一个很长的 HTML 表格中解析信息;现在我使用的代码使用 DOMDocument、DOMElement (etc) 类进行解析。我想做一个性能测试,运行当前方法,反对正则表达式从表中提取信息,但我无法得到正确的表达式。

表格的 HTML 行如下所示:

<tr><td>   JON SMITH     </td><td> 2000-09-29 </td></tr>

我一直在尝试的表达式看起来像这样:

/(?:<td>([a-zA-Z\s]*?)<\/td><td>([0-9-\s]*?)<\/td>)/

上述表达式的问题在于它返回整个行内容,而不仅仅是内列内容。理想情况下,preg_match_all 数组结果将是名称、日期、名称、日期等。

这是一个合理的做法,还是我应该坚持使用 DOM 技术?如果它是合理的,有人可以帮助正则表达式吗?

谢谢!

编辑:如果将来有人偶然发现这一点,RegEx 解决方案的性能要比使用 DOM 类好得多;在我的情况下,这是秒和分钟之间的差异。

4

2 回答 2

0

我的解决方案:

第1步。搜索<table>...</table>
/<table[^>]*+>([^<]*+(?:(?!<\/?+table)<[^<]*+)*+)<\/table>/i

第2步。<tr>...</tr>从 step1 group1 中搜索所有:
/<tr[^>]*+>([^<]*+(?:(?!<\/?+tr)<[^<]*+)*+)<\/tr>/ix

第三步。<td>...</td>从每个(来自 step2 group1)中提取数据:
/<td[^>]*+>([^<]*+(?:(?!<\/?+td)<[^<]*+)*+)<\/td>/ix

这些可怕的模式是指Mastering Regular Expressions 3rd

示例代码:

    <?php
$foo = '<tr><td>   JON SMITH     </td><td> 2000-09-29 </td></tr>';
if(preg_match_all('/<td[^>]*+>([^<]*+(?:(?!<\/?+td)<[^<]*+)*+)<\/td>/ix', $foo, $matches) > 0){
    for($i = 0; $i < count($matches[0]); ++$i)
        printf("%s\n", $matches[0][$i]);

    for($i = 0; $i < count($matches[1]); ++$i)
        printf("%s\n", $matches[1][$i]);
}
?>

输出:

<td>   JON SMITH     </td>
<td> 2000-09-29 </td>
JON SMITH
2000-09-29
于 2012-08-02T13:51:56.973 回答
0

使用 preg_match_all() 并传递带有要填充的数组的第三个参数和第四个参数 PREG_SET_ORDER。

preg_match_all("/(?:<td>([a-zA-Z\s]*?)<\/td><td>([0-9-\s]*?)<\/td>)/", $html, $matches, PREG_SET_ORDER);

结果数组应该是这样的:

$matches => array(
   [0] => array(
      [0] => '<td>   JON SMITH     </td><td> 2000-09-29 </td>',
      [1] => '   JON SMITH     ',
      [2] => ' 2000-09-29 '
   ),
   [1] => array(
      [0] => '<td>   JACK BOLD     </td><td> 2000-10-20 </td>',
      [1] => '   JACK BOLD     ',
      [2] => ' 2000-10-20 '
   ),
   ...
);

请参阅preg_match_all() 文档。

于 2012-08-02T13:57:00.747 回答