代码之家  ›  专栏  ›  技术社区  ›  HyderA

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

  •  0
  • HyderA  · 技术社区  · 15 年前

    我有一些像这样的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 , efgh ijkl

    这是我当前使用的regex:

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

    是的,我对他们不是很在行。和我大多数的regex尝试一样,这不起作用。有人能告诉我为什么吗?

    另外,我知道HTML/XML解析器,但要实现这一点,需要对代码进行重要的重新访问。那是以后的事了。我们现在需要继续使用regex。

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

    6 回复  |  直到 15 年前
        1
  •  2
  •   jensgram    15 年前
    ~<tr class="row-(even|odd)">\s*<td align="center">(.*?)</td>~m
    

    注意到 m 修饰语及其使用 \s* .

    此外,您还可以通过 ?: . 即。, (?:even|odd) 因为你可能对 class 属性:

        2
  •  2
  •   codaddict    15 年前

    试试这个:

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

    变化:

    • 你还没算上新线 在标签之间
    • 你不需要X修改器 将丢弃regex中的空间。
    • 通过使用使匹配不贪婪 .*? 代替 .* .

    Working link

        3
  •  2
  •   Gordon Haim Evgi    15 年前

    实际上,您不需要对代码库进行太大的更改。获取文本节点总是与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
    )
    

    但是如果你想要一个regex,使用regex。我只是在想办法。

        4
  •  0
  •   mellowsoon    15 年前

    这就是我想到的

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

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

        5
  •  0
  •   W3Coder    15 年前

    免责声明:使用regexps解析HTML是危险的。

    要获取每个tr中第一个td的innerhtml,请使用以下regexp:

    /<tr[^>]*>\s*<td[^>]>(.+?)<\/td>/si
    
        6
  •  0
  •   Swiss    15 年前

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

    <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=([^"]+)