繁体   English   中英

PHP Regex从非捕获组中提取内部内容

[英]PHP Regex Extract Inner Content From Non-Capturing Group

我正在从一个很长的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类更好; 在我的情况下,这是秒和分钟之间的差异。

我的解决方案:

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

第2步。 从步骤1组1中搜索所有<tr>...</tr>
/<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

使用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()文档。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM