从表中的每个第一个TD中提取内容

时间:2010-10-19 07:08:14

标签: php regex preg-match-all

我有一些看起来像这样的HTML:

<tr class="row-even">
    <td align="center">abcde</td>
    <td align="center"><a href="deluserconfirm.html?user=abcde"><img src="../images/delete_x.gif" alt="Delete User" border="none" /></a></td>
</tr>
<tr class="row-odd">
    <td align="center">efgh</td>
    <td align="center"><a href="deluserconfirm.html?user=efgh"><img src="../images/delete_x.gif" alt="Delete User" border="none" /></a></td>
</tr>
<tr class="row-even">
    <td align="center">ijkl</td>
    <td align="center"><a href="deluserconfirm.html?user=ijkl"><img src="../images/delete_x.gif" alt="Delete User" border="none" /></a></td>
</tr>

我需要检索值abcdeefghijkl

这是我正在使用的正则表达式:

preg_match_all('/(<tr class="row-even">|<tr class="row-odd">)<td align="center">(.*)<\/td><\/tr>/xs', $html, $matches);
是的,我不是很擅长他们。与我的大部分正则表达式尝试一样,这不起作用。谁能告诉我为什么?

另外,我知道html / xml解析器,但需要重新编写代码才能实现。所以这是为了以后。我们现在需要坚持使用正则表达式。

编辑:为了澄清,我需要在<td align="center"></td><tr class="row-even">之后的第一个<tr class="row-odd">标记之间的值

6 个答案:

答案 0 :(得分:2)

~<tr class="row-(even|odd)">\s*<td align="center">(.*?)</td>~m

请注意m修饰符和\s*的使用。

此外,您可以通过?:使第一组无法捕获。即{,(?:even|odd),因为您可能对class属性不感兴趣:)

答案 1 :(得分:2)

试试这个:

preg_match_all('/(?:<tr class="row-even">|<tr class="row-odd">).<td align="center">(.*?)<\/td>/s', $html, $matches);

所做的更改:

  • 你没有说明换行符 标签之间
  • 您不需要x修饰符 将丢弃正则表达式中的空格。
  • 使用,使匹配非贪婪 .*?取代.*

Working link

答案 2 :(得分:2)

实际上,您不需要对代码库进行太大的更改。获取文本节点与DOM和XPath始终相同。所有改变的都是XPath,因此您可以将DOM代码包装成一个替换preg_match_all的函数。这只是一个微小的变化,例如。

include_once "dom.php";
$matches = dom_match_all('//tr/td[1]', $html);

dom.php只包含:

// dom.php
function dom_match_all($query, $html, array $matches = array()) {
    $dom = new DOMDocument;
    libxml_use_internal_errors(TRUE);
    $dom->loadHTML($html);
    libxml_clear_errors();
    $xPath = new DOMXPath($dom);
    foreach( $xPath->query($query) as $node ) {
        $matches[] = $node->nodeValue;
    }
    return $matches;
}

并将返回

Array
(
    [0] => abcde
    [1] => efgh
    [2] => ijkl
)

但是如果你想要一个正则表达式,请使用正则表达式。我只是在提出想法。

答案 3 :(得分:0)

这只是一个快速而肮脏的正则表达式,以满足您的需求。它可以很容易地清理和优化,但它是一个开始。

<tr[^>]+>[^\n]*\n               #Match the opening <tr> tag
  \s*<td[^>]+>([^<]+)[^\n]+\n   #Group the wanted data
  [^\n]+\n                      #Match next line
</tr>                           #Match closing tag

这是另一种可能更强大的方法:

deluserconfirm.html\?user=([^"]+)

答案 4 :(得分:0)

这就是我想出来的

<td align="center">([^<]+)</td>

我会解释。这里的挑战之一是标签之间可能是您要查找的文本或标签。在正则表达式中,[^&lt;] +表示匹配的一个或多个字符&lt;字符。这很好,因为这意味着不匹配,并且该组只会匹配,直到找到标签。

答案 5 :(得分:0)

免责声明:使用正则表达式解析HTML是危险的。

要获取每个TR中第一个TD的innerhtml,请使用此正则表达式:

/<tr[^>]*>\s*<td[^>]>(.+?)<\/td>/si