在特定字符串后使用preg_match查找模式的所有连续出现

时间:2013-09-04 12:11:25

标签: php regex html-parsing

我有一个庞大的html文档,其中包含具有唯一表ID的不同表。类似的东西:

<table class="my_table" id="table_id1">
  <tr class="odd"><td>Line 1</td></tr>
  <tr class="even"><td>Line 2</td></tr>
  <tr class="odd"><td>Line 3</td></tr>
  <tr class="even"><td>Line 4</td></tr>
</table>
<table class="my_table" id="table_id2">
  <tr class="odd"><td>Line 1</td></tr>
  <tr class="even"><td>Line 2</td></tr>
  <tr class="odd"><td>Line 3</td></tr>
</table>

是否可以使用preg_match查找特定表的所有行的HTML?

我尝试了以下代码:

preg_match('/<table[^>]*id="table_id2">(<tr[^>]*><td>[^>]*<\/td><\/tr>)+/', $html, $matches); 
//$html variable contains the html.

但它返回输出,如:

Array
(
    [0] => Array
        (
            [0] => <table class="my_table" id="table_id2"><tr class="odd"><td>Line 1</td></tr><tr class="even"><td>Line 2</td></tr><tr class="odd"><td>Line 3</td></tr>
        )

    [1] => Array
        (
            [0] => <tr class="odd"><td>Line 3</td></tr>
        )

)

但我需要这样的输出:

Array
(
    [0] => Array
        (
            [0] => <table class="my_table" id="table_id2"><tr class="odd"><td>Line 1</td></tr><tr class="even"><td>Line 2</td></tr><tr class="odd"><td>Line 3</td></tr>
        )

    [1] => Array
        (
            [0] => <tr class="odd"><td>Line 1</td></tr>
            [1] => <tr class="odd"><td>Line 2</td></tr>
            [2] => <tr class="odd"><td>Line 3</td></tr>
        )

)

有可能吗?请帮忙。

2 个答案:

答案 0 :(得分:2)

您不应该使用正则表达式来解析HTML。 PHP有一个很好的工具 - DOMDocument。使用它,你可以做许多事情,这是正则表达式不可能/几乎不可能的。您的样本将如下所示:

$sHtml = '<table class="my_table" id="table_id1">
  <tr class="odd"><td>Line 1</td></tr>
  <tr class="even"><td>Line 2</td></tr>
  <tr class="odd"><td>Line 3</td></tr>
  <tr class="even"><td>Line 4</td></tr>
</table>
<table class="my_table" id="table_id2">
  <tr class="odd"><td>Line 1</td></tr>
  <tr class="even"><td>Line 2</td></tr>
  <tr class="odd"><td>Line 3</td></tr>
</table>';

$rDoc   = new DOMDocument();
$rDoc->loadHTML($sHtml);
$sId    = 'table_id2';
//found table:
$rTable = $rDoc->getElementById($sId);
foreach($rTable->childNodes as $rItem)
{
   //do something with item:
   //var_dump($rItem);
}

答案 1 :(得分:0)

试试this。它与你所拥有的非常相似,但我在每一行周围放置了一个非捕获分组,以及每行中的一些前导和尾随可选空格。

作为参考,使用的正则表达式是

/<table[^>]*id="table_id2">((?:\s*<tr[^>]*><td>[^>]*<\/td><\/tr>\s*)+)/