【问题标题】:Find all <pre> tags in PHP (with attributes)查找 PHP 中的所有 <pre> 标签(带有属性)
【发布时间】:2013-11-14 20:15:35
【问题描述】:

我正在关注this question,了解如何在 PHP 中检索所有标签。

特别是(在 wordpress 下),我想查找所有&lt;pre&gt;标签,以及所有可用信息(属性和文本)。但是,我似乎对preg_match 不太熟练,所以我向您求助。

我的文本确实包含各种&lt;pre&gt; 标签,有些带有属性,有些只有文字。我的功能是这样的:

function getPreTags($string) {
    $pattern = "/<pre\s?(.*)>(.*)<\/pre>/";
    preg_match($pattern, $string, $matches);
    return $matches[1];
}

我已经简化为只有 一个 &lt;pre&gt; 标签的测试,但我得到了 count(getPreTags(myHTMLbody)) = 0,我不知道为什么。这是测试字符串:

<pre class="wp-code-highlight prettyprint prettyprinted" style=""><span class="com">Whatever &lt;</span> I've written &gt;&gt; here <span class="something">should be taken care of</span></pre>

有什么提示吗?

干杯!

【问题讨论】:

  • 不使用贪婪匹配器.*? 来获取所有&lt;pre ...&gt;,所以你最终得到/&lt;pre\s?(.*?)&gt;(.*?)&lt;\/pre&gt;/
  • 我不明白。我试过"/&lt;pre\s?.*?&gt;(.*)&lt;\/pre&gt;/",但它仍然给我count(matches[0]) = 0
  • 使用完全我上面的模式。
  • 好的,但我仍然使用echo count(getPreTags($obj)); 得到计数 0,其中函数是我的函数,模式为 /&lt;pre\s?(.*?)&gt;(.*?)&lt;\/pre&gt;/...
  • 我通过count() 得到1,您的函数返回值与您在上面发布的完全相同的HTML 字符串。在将原始 HTML 字符串发布到此处之前,您是否清除了任何换行符?

标签: php regex wordpress tags


【解决方案1】:

与以往一样,使用正则表达式解析 HTML 永远不会减少它。有很多事情需要考虑(标签汤,间距:&lt;pre&gt;==&lt; pre &gt;==&lt;\n\t\sPrE\n\n&gt;...),任何正则表达式都会在某些时候让你失望。这就是为什么有现成的解析器之类的东西。

也就是说:当您需要所有 pre 标签(包括那些没有属性的标签)时,我不知道为什么其他答案会遇到使用DOMXPath 实例的麻烦。
我会选择更简单的东西,例如:

$dom = new DOMDocument;
$dom->loadHTML($htmlString);
$preTags = $dom->getElementsByTagName('pre');
foreach($preTags as $pre)
{
    echo $pre->nodeValue, PHP_EOL;
    if ($pre->hasAttributes())
    {//if there are attributes
        foreach($pre->attributes as $attribute)
        {
            //do something with attribute
            echo 'Attribute: ', $attribute->name, ' = ', $attribute->value, PHP_EOL;
        }
    }
}

您可以在这些页面上轻松找到可用的方法和属性:

【讨论】:

    【解决方案2】:

    您最好使用 DOM 解析器来解析 HTML。考虑这段代码:

    $html = <<< EOF
    <a href="http://example.com/foo.htm" class="curPage">Click link1</a> morestuff
    <pre>A    B    C</pre>
    <a href="http://notexample.com/foo/bar">notexample.com</a> morestuff
    <pre id="pre1">X    Y    Z</pre>
    <a href="http://example.com/foo.htm">Click link1</a>
    <pre id="pre2">1    2    3</pre>
    EOF;
    
    // create a new DOM object
    $doc = new DOMDocument();
    libxml_use_internal_errors(true);
    $doc->loadHTML($html); // loads your html
    $xpath = new DOMXPath($doc);
    
    // select all pre tags with attributes
    $nodelist = $xpath->query("//pre[@*]");
    
    // iterate through selected nodes and print them
    for($i=0; $i < $nodelist->length; $i++) {
        $node = $nodelist->item($i);
        var_dump($node->nodeValue);
    }
    

    输出:

    string(11) "X    Y    Z"
    string(11) "1    2    3"
    

    【讨论】:

    • 虽然这是一个非常好的解决方案,但我没有整个 DOM,只有一个 wordpress 项目的内容:(
    • @senseiwa:如上例所示,您不需要整页 (DOM) 即可使其工作。
    • 嗯,那么我的代码中有一些问题:它停止评估。在这里 (pastebin.com/a5peRVp6) 你可以找到我的代码:$obj 包含 wordpress 项目。该函数只会打印“START”,然后停止。
    • 你能在这个函数的开头调用var_dump($obj);来显示$obj的内容吗?
    • @senseiwa:我没有看到你的 HTML 内容。您可以通过编辑您的问题或在 pastebin 上将其粘贴到此处吗?
    【解决方案3】:

    如果数据符合 XML,您可以使用 XPATH 表达式。

    只是一个非常快的:

    <?xml version="1.0" encoding="UTF-8"?>
    <html>
      <head>
        <title>Test</title>
      </head>
      <body>
        <pre>1</pre>
        <pre>2</pre>
        <pre>3</pre>
      </body>
    </html>
    

    然后是这样的 PHP:

    <?php
            $xmldoc = new DOMDocument();
            $xmldoc->load('test.xml');
    
            $xpathvar = new Domxpath($xmldoc);
    
    echo $xpathvar->evaluate('count(*//pre)');
    ?>
    

    这也应该适用于 html/xml sn-ps。

    【讨论】:

    • 不幸的是,wordpress 不允许我挂钩所有方面(我不是那么熟练),但我可以检索项目的字符串,这不是真正的 DOM……跨度>
    猜你喜欢
    • 2015-08-23
    • 2011-04-16
    • 2012-05-09
    • 2021-06-12
    • 2011-07-01
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多