【问题标题】:Using regexes to find result from HTML table使用正则表达式从 HTML 表中查找结果
【发布时间】:2013-06-16 19:25:52
【问题描述】:

我遇到了一些正则表达式问题。

我有一个巨大的 html 文件,我需要从文件中提取一些文本(型号)。

<table>......
<td colspan="2" align="center" class="thumimages"><b>SK10014</b></td></tr> 
.......

<table>/.....
<td colspan="2" align="center" class="thumimages"><b>SK1998</b></td></tr> 

.... so on

这是一个巨大的页面,所有网页都内置于表格和无div...

“thumimages”类几乎在所有 td 中重复,因此无法区分页面中需要的内容。

大约有10000个型号,我需要提取它们。

有没有办法用正则表达式做到这一点......就像

"/<td colspan="2" align="center" class="thumimages"><b>{[1-9]}</b></td></tr>/"

并返回所有匹配结果的数组。注意我已经尝试过 HTML 解析,但文档包含许多 html 验证错误。

任何帮助将不胜感激...

【问题讨论】:

  • 不要使用正则表达式解析 HTML。您无法使用正则表达式可靠地解析 HTML,并且您将面临悲伤和挫败感。一旦 HTML 与您的期望发生变化,您的代码就会被破坏。有关如何使用已经编写、测试和调试的 PHP 模块正确解析 HTML 的示例,请参阅 htmlparsing.com/php

标签: php regex html-parsing


【解决方案1】:

说明

这将匹配所有td 字段与class="thumimages" 并检索内部b 标记的内容。内部文本需要有一些价值,任何前导或尾随空格都将被删除。

&lt;td\b(?=\s)(?=[^&gt;]*\s\bclass=(["'])thumimages\1)[^&gt;]*&gt;&lt;b&gt;\s*(?!&lt;)([^&lt;\s]+)\s*&lt;\/b&gt;&lt;\/td&gt;

Group 0 获取从打开标签到关闭标签的整个 td 标签

  1. 获取围绕类值的打开引号,以确保也找到正确的关闭捕获
  2. 得到想要的文字

PHP 代码示例:

输入文字

<table>......
<td colspan="2" align="center" class="thumimages"><b>SK10014</b></td></tr> 
.......
<table>/.....
<td colspan="2" align="center" class="thumimages"><b>     </b></td></tr> 


<table>/.....
<td colspan="2" align="center" class="thumimages"><b>   SK1998    </b></td></tr> 

代码

<?php
$sourcestring="your source string";
preg_match_all('/<td\b(?=\s)(?=[^>]*\s\bclass=(["'])thumimages\1)[^>]*><b>\s*(?!<)([^<\s]+)\s*<\/b><\/td>/imsx',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>
 

匹配

$matches Array:
(
    [0] => Array
        (
            [0] => <td colspan="2" align="center" class="thumimages"><b>SK10014</b></td>
            [1] => <td colspan="2" align="center" class="thumimages"><b>   SK1998    </b></td>
        )

    [1] => Array
        (
            [0] => "
            [1] => "
        )

    [2] => Array
        (
            [0] => SK10014
            [1] => SK1998
        )

)

【讨论】:

    【解决方案2】:

    使用 DOMDocument 的方法:

    // $html stands for your html content
    $doc = new DOMDocument();
    @$doc->loadHTML($html);
    $td_nodes = $doc->getElementsByTagName('td');
    
    foreach($td_nodes as $td_node){
        if ($td_node->getAttribute('class')=='thumimages')
            echo $td_node->firstChild->textContent.'<br/>';
     }
    

    使用正则表达式的方法:

    $pattern = <<<'LOD'
    ~
    <td (?>[^>c]++|\bc(?!lass\b))+ # begining of td tag until the word "class" 
    class \s*+ = \s*+              # "class=" with variable spaces around the "="
    (["']?+) thumimages\b \1       # "thumimages" between quotes or not 
    (?>[^>]++|(?<!b)>)+>           # all characters until the ">" from "<b>"
    \s*+  \K                       # any spaces and pattern reset
    
    [^<\s]++                    # all chars that are not a "<" or a space
    ~xi
    LOD;
    
    preg_match_all($pattern, $html, $matches);
    
    echo '<pre>' . print_r($matches[0], true);
    

    【讨论】:

    • 我同意 HTML 解析可能是最好的解决方案,但是请求者确实在此处对另一个答案发表了评论,称 html 源代码格式不正确并且正在丢弃验证错误。
    【解决方案3】:
    /(<td colspan="2" align="center" class="thumimages"><b>)([a-z0-9]+)(</b></td></tr>)/i
    

    这行得通。

    【讨论】:

    • 我用这个得到一个空白数组.. Array ( [0] => Array ( ) [1] => Array ( ) [2] => Array ( ) [3] => Array ( ) )....
    • 我用 preg_match_all('|()([a-z0-9]+)()|i', $content, $matchesarray);
    • 我认为您需要使用 \ 某些 html 字符(例如 / )转义,也许 =
    【解决方案4】:

    可以使用phpDOMDocument

    <?php
        $dom = new DOMDocument();
        @$dom->loadHTMLFile('load.html');
        $xpath = new DOMXPath($dom);
    
         foreach($xpath->query('//tr') as $tr){
            echo $xpath->query('.//td[@class="thumimages"]', $tr)->item(0)->nodeValue.'<br/>';
         }
    ?>
    

    【讨论】:

    • 试过了,但是文档包含很多 html 验证错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多