我正在从一个很长的HTML表中解析信息;现在我正在使用的代码使用DOMDocument,DOMElement(etc)类进行解析。我想做一个性能测试来运行当前的方法来对抗Regex从表中获取信息,但我无法得到正确的表达式。
表格的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类更好;在我的情况下,这是秒与分钟之间的差异。
答案 0 :(得分:0)
我的解决方案:
步骤1。搜索<table>...</table>
:
/<table[^>]*+>([^<]*+(?:(?!<\/?+table)<[^<]*+)*+)<\/table>/i
步骤2。从step1 group1搜索所有<tr>...</tr>
:
/<tr[^>]*+>([^<]*+(?:(?!<\/?+tr)<[^<]*+)*+)<\/tr>/ix
步骤3。从每个<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
答案 1 :(得分: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 '
),
...
);