0

我有一些看起来像这样的 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>

我需要检索值abcde、、、efghijkl

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

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">

4

6 回答 6

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

注意m修饰符和\s*.

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

于 2010-10-19T07:31:15.040 回答
2

试试这个:

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

所做的更改:

  • 您没有考虑标签之间的换行符
  • 您不需要 x 修饰符,因为它会丢弃正则表达式中的空间。
  • .*?通过使用代替.使匹配非贪婪 .*

工作链接

于 2010-10-19T07:36:22.033 回答
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
)

但是,如果您想要正则表达式,请使用正则表达式。我只是给出想法。

于 2010-10-19T07:46:37.477 回答
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=([^"]+)
于 2010-10-19T07:29:48.860 回答
0

这就是我想出的

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

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

于 2010-10-19T07:34:39.660 回答
0

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

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

/<tr[^>]*>\s*<td[^>]>(.+?)<\/td>/si
于 2010-10-19T07:36:25.433 回答