【问题标题】:Extract multiple from html从html中提取多个
【发布时间】:2017-06-23 16:53:15
【问题描述】:

我正在尝试提取下面 <li> </li> 标记中的单词。我的正则表达式运行良好,但只给了我第一个 <li>Lorem ipsum...

我对正则表达式相当陌生,我知道通过遍历 DOM 可能更可靠,但在这种情况下,更喜欢正则表达式。有什么想法我需要改变才能获得所有结果,而不仅仅是一个?

/<div class="foo-bar">[\s\S]+<ul>[\s\S]*?(<li>([\s\S]*?)<\/li>)+[\s\S]*?<\/ul>/

<div class="foo-bar">
    <!-- Other junk -->
    <ul>
        <li>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        </li>
        <li>
            Vestibulum iaculis nibh ac orci imperdiet ultrices.
        </li>
        <li>
            Fusce neque lacus, feugiat eget sapien eget, ullamcorper rutrum mauris.
        </li>
        <li>
            Maecenas in ipsum consectetur, finibus ex et, condimentum turpis.
        </li>
    </ul>
    <!-- Other junk -->
</div>

【问题讨论】:

  • 你的 PHP 代码是什么样的?
  • 不要使用正则表达式。使用解析器。 php.net/manual/en/domdocument.getelementsbytagname.php 要使用正则表达式,您需要提取完整的 ul,然后解析出每个 li
  • 还不存在,只是对正则表达式进行原型设计。只需要像上面那样摆弄一个 sn-p。
  • 我也读过。 :) 我仍然认为它适合您的问题,因为您可能要求单个正则表达式做太多事情。

标签: php html regex xml dom


【解决方案1】:

使用 DOM+Xpath 而不是 RegEx。

$document = new DOMDocument();
$document->loadHTML($html);
$xpath = new DOMXpath($document);

foreach($xpath->evaluate('//div[@class="foo-bar"]/ul/li') as $li) {
  var_dump($li->textContent);
}

输出:

string(80) "
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        "
string(75) "
            Vestibulum iaculis nibh ac orci imperdiet ultrices.
        "
string(95) "
            Fusce neque lacus, feugiat eget sapien eget, ullamcorper rutrum mauris.
        "
string(89) "
            Maecenas in ipsum consectetur, finibus ex et, condimentum turpis.
        "

【讨论】:

  • 否则答案很好。
  • 我做到了。您可能不想使用 XML 解析器,但它是更好的解决方案。所以我为其他可能有同样问题的人发布了更多答案并找到你的问题。
【解决方案2】:

在末尾添加全局 g 标志。例如:

/<div class="foo-bar">[\s\S]+<ul>[\s\S]*?(<li>([\s\S]*?)<\/li>)+[\s\S]*?<\/ul>/g

您可能还需要i 标志以不区分大小写

【讨论】:

  • PHP 中没有gphp.net/manual/en/reference.pcre.pattern.modifiers.php 函数是否为全局函数。
  • @chris85 代替g 你可以使用preg_match_all() 函数
  • @funilrys 是的,The functions are global or not. 仍然没有 g 修饰符。
  • @funilrys Yup preg_match_all() 仍然只匹配一个。 :(
  • @Eamonn 是的,这不是答案。正则表达式不会像你想要的那样工作。
【解决方案3】:

最好将以下内容与preg_match_all() 一起使用。我刚刚测试了它here,它正在工作。

preg_match_all下面的内容只获取`

/<div class="foo-bar">([\s\S]*?)+<ul>([\s\S]*?)<\/ul>([\s\S]*?)<\/div>/

然后preg_match_all将前一个preg_match_all的结果加上下面就只能得到&lt;li&gt;的内容

/<li>([\s\S]*?)<\/li>/

【讨论】:

  • 这是我需要的,但它还需要 &lt;div class="foo-bar"&gt;&lt;ul&gt; 包装器来阻止它匹配其他东西。
  • @Eamonn 我相信这在单个正则表达式中是不可能的。把它分成两个正则表达式?
  • 看起来这将是解决方案。如果你想更新你的答案,我会接受。
  • @Eamonn 编辑了我的答案你能测试一下吗?
猜你喜欢
  • 2019-07-21
  • 2020-01-07
  • 2016-12-12
  • 2012-06-27
  • 2021-06-15
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多