如何preg_match父div?

时间:2010-07-19 02:53:27

标签: php regex preg-match

我需要使用preg_match,

获取div class =“parent”的所有内容
<div class = "parent">

    <div id = "child1">
    </div>

    <div id = "child2">
    </div>

</div>

任何?

3 个答案:

答案 0 :(得分:2)

执行此操作的正确方法是使用the DOMxpath来定位您尝试提取的特定元素和属性。但是,由于这是家庭作业,让我们教育你的导师。

鉴于完全字符串,此正则表达式将起作用:!<div class = "parent">(.+)</div>!s

关键是“s”修饰符。它将“.”字符从“除换行符之外的任何内容”转换为“包含换行符的任何内容。”

但是,如果在=周围删除空格,则会中断。如果有更多属性,它会破坏。如果有更多的类名,这将会破坏。换句话说,这是处理HTML 永远的最糟糕方式。

天啊,如果HTML看起来像这样,它会破坏:

<div>
    <div class = "parent">
        My spoon is too big!
        <div>
            I am a banana!
        </div><!-- Matches when un-greedy -->
    </div>
</div><!-- Matches when greedy -->

为什么呢?因为.+是所谓的“贪婪”。它将匹配它可能的所有内容,直到下一个子句。这意味着它将匹配从div.parent到贪婪评论的所有内容。虽然可以通过添加问号(.+?)使其变得非贪婪,但它会匹配第一个可能的下一个子句,而不是最后一个可能的下一个子句。这意味着它将匹配从div.parent到非贪婪评论的所有内容。

由于嵌套问题,正则表达式是解析HTML的非常差的工具。我在这里向您展示的问题只涉及等待您的h̨̜̜̟̬̭͍o̶̻̹̥̻ͧ̆͆̊̉̍r̟͓ͨ͆ͨr̪̖̠̖̤̊̾ͣͦo̡̬͉͈͚̙͙ͯ͑ͨ͒ͥͩ̇ȓ̵̥̙͈̟s̠̏̊͠的表面。

请尽可能使用真正的HTML / XML解析器并使用生成的DOM。它会拯救你的理智。

答案 1 :(得分:0)

出于您的目的,这可能会有所作为,尽管它并非没有问题(如链接中所述):

preg_match('/<div class = \'parent\'>(.*)<\/div>/s',$input,$matches);

之后,$ matches [0]将包含匹配的文本(包括父div),$ matches [1]将仅包含内部项目。

答案 2 :(得分:0)

你最终会得到像这样野蛮的东西:

/<div[^>]+class ?= ?"parent"[^>]*>(\s*(?:<div.*<\/div>\s*)*)<\/div>/Us

首先,在开始div标签内搜索所需的类 - 我喜欢使用[^&gt;]这是一个字符组,指定除“&gt;”之外的任何内容字符。然后在“=”(或不是)周围留出空格。

然后基本的想法是将每个后续的开始div标签与它的闭合配对配对,以便能够在正确的位置停止。这是通过可以重复0次或更多次的非捕获子模式完成的。请注意,这仅适用于一级嵌套。为了解决这个问题,你需要递归并且难以概念化。

递归版本看起来像这样:

/<div[^>]+class ?= ?"parent"[^>]*>(\s*(<div.*(?2).*<\/div>\s*)*)<\/div>/Us

总的来说,如果我不能做出理智的事情并且使用DOM我宁愿遍历字符串(每次从上一个匹配开始)为我遇到的每个开始div标签递增一个计数器并递减它每个结束标记。

请注意,这些都是我的头脑,为了学习正则表达式而发布,而不是用正则表达式解析html是理智的。此外,我不想看到正则表达式引擎必须经历的健美操日志,以平衡所有这些通配符。