【问题标题】:Get first image after one special sting with PHP [closed]使用 PHP 在一个特殊字符串之后获取第一张图像 [关闭]
【发布时间】:2014-07-16 19:54:49
【问题描述】:

我有一个简单的问题。想象一下我们下面有这个 HTML 字符串:

<html>
    <body>
        <img src="one.png">
            <div class="something">

            KEYHERE

            <img src="address.png">

            Some text       
            Lorem ipsum ... 
            <img src="two.png">
            </div>
    </body>
</html>

现在,顶部 HTML 代码中有一个 KEYHERE

我有一个这样的 php 变量:

$key = "KEYHERE";

现在,我想在那个键之后得到第一张图片src(地址)。

例如,关于那个顶级代码,我需要在我的 php 代码中获取address.png 地址才能使用它。

我该怎么做?

【问题讨论】:

  • 你怎么称呼这个?您是否使用 PHP cURL 来获取上述 HTML?这是在同一页面中调用的吗?请多解释一下这里发生了什么。
  • @BrandonWhite HTML 页面可以通过任何方式访问!这不重要,重要的是我们有一个 HTML 代码,并且想从我们的 Key 的下一个获取第一个 img 地址 :)
  • 你有没有尝试过这个?您可以使用正则表达式,甚至可以简单地获取$key 的strpos 并删除它之前的所有内容,然后找到第一个&lt;img 的strpos 并尝试提取src。
  • “以任何方式访问”意味着您未能解释回答此问题所需的关键信息。
  • @Diodeus HTML 字符串的获取方式对解析无关紧要,也不应该在意。这当然不是“回答这个问题所需的关键信息”。 OP 是对的。

标签: php html regex curl preg-match


【解决方案1】:

以下代码使用 PHP 中的原生 DOM 解析器 (DOMDocument) 和 XPath 实现来查找节点。

这段代码将首先找到您的关键字。一旦找到关键字,它将检查节点的兄弟节点以找到同一级别上的第一个 img 标记(如果有)。

// gets the first matching sibling (first image found in the dom tree on the same level)
function getFirstImageTag(DOMNode $node) {
    while ($node->nextSibling) {
        $node = $node->nextSibling;

        if ($node->nodeName !== 'img') continue;

        return $node->getAttribute('src');
    }
}

// parses the document / finds the keyword in the html string
function parse($html, $keyword) {
    $dom = new DOMDocument();
    $dom->loadHTML($html);
    $xpath = new DOMXPath($dom);

    // you can use a more strict check here if you are sure the keyword is the only thing in the textnode
    $textNodes = $xpath->evaluate("//text()[contains(.,'$keyword')]");

    foreach ($textNodes as $textNode) {
        if (trim($textNode->textContent) === $keyword) {
            return getFirstImageTag($textNode);
        }
    }
}

echo parse($content, 'KEYHERE');

以上示例基于您的示例 HTML,其中关键字位于文本节点中。如果不是这种情况,上面的代码应该很容易“修复”到您的需求。

注意:这个答案做了很多假设。它总是一个文本节点吗? img 标签是否总是在树的同一分支中(即使在同一级别)?关键字和img标签之间会不会有其他节点。

演示:http://codepad.viper-7.com/8GkLhW

【讨论】:

    【解决方案2】:
    <?php
    
    $key = 'Test';
    $html = '<html><body>Test <img src="http://example.com" /></body></html>';
    
    $tmp = substr($html, strpos($html, $key));
    $start = strpos($tmp, 'src="')+5; 
    $tmp = substr($tmp, $start);
    $end = strpos($tmp, '"');
    
    echo substr($tmp, 0, $end);
    

    http://runnable.com/U8behz5Pfi4HipDa/get-first-image-after-one-special-sting-with-php

    【讨论】:

    • 没什么私人的,但我不想成为继承这段代码的人
    • 很高兴不使用正则表达式!嘘不使用解析器!是的,有一个有效的例子。嘘有一个不适用于大多数 HTML 的示例。是的……我不确定。嘘所有的东西。
    • 所以,如果密钥的长度发生变化,代码又会发生变化!
    • 我想过使用解析器,但对于这种情况,它确实是最重要的。只是处理问题中给出的数据。
    【解决方案3】:

    你应该在这里使用正则表达式。

    您可以使用以下代码:

    <?php
    
    $content = '<html>
        <body>
            <img src="one.png">
                <div class="something">
    
                KEYHERE
    
                <img src="address.png">
    
                Some text       
                Lorem ipsum ... 
                <img src="two.png">
                </div>
        </body>
    </html>';
    
    
    preg_match('/(?:KEYHERE\s*)<img(?:\s*)src="(\S*)"/i',$content, $matches);
    
    echo $matches[1];
    

    获取address.png

    【讨论】:

    • 最好使用src="[^"]+" 以确保您不会从.* 中得到一些疯狂的结果,即对于KEYHERE &lt;img src="address.png"&gt; &lt;img src="address2.png"&gt;,您的表达式匹配address.png"&gt; &lt;img src="address2.png
    • 感谢亲爱的 Marchin,如果我们有两把钥匙,该怎么办?
    • @Pap 然后你可以用(?:(?:KEYHERE|KEYTWO)\s*)代替(?:KEYHERE\s*)
    • @MarcinNabiałek 非常感谢,我看到你在上一条评论中使用了|。所以,如果我需要同时检查 Key1 和 Key2(如果它们都是),那么找到第一个图像该怎么办?我认为这个| 表示OR,我们如何在这里使用AND 命令?同时拥有它们。
    • 如果您在 img 之前同时需要它们,您应该将需要在 img 之前的整个字符串放在这里。在|注解中,它意味着它将找到所有工作前有keyhere或keytwo的img
    猜你喜欢
    • 1970-01-01
    • 2011-07-31
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 2019-12-13
    • 1970-01-01
    • 2020-11-19
    相关资源
    最近更新 更多