使用正则表达式匹配具有特定ID的div块

时间:2011-03-18 17:08:24

标签: php html regex

我正在尝试匹配具有特定ID的div块。这是我的正则表达式代码:

<div\s+[^>]*\s*id\s*=\s*["|']content["|']\s*>[^/div]+

我希望正则表达式匹配整个div块。所以我把[^ / div] +放在我的正则表达式中,我假设它会匹配剩余的字符,直到它到达结尾但是它不能匹配直到结束,因为[^]表达式认为我不想要匹配任何&lt; / | d |我| v |取代。我想要的是将整个事情视为一个整体。放置一个[^()]也没有帮助..

所以请告诉我应该如何编码这个问题

<div id="content">
    <noscript></noscript>
    <a href="blabla.com">
    <h1>
       <a href="blablac.com">Blablabla</a>
    </h1>
</div>

5 个答案:

答案 0 :(得分:21)

答案 1 :(得分:3)

[^ / div] +会在到达任何这些字符时停止,这不是你想要的。由于 i ,它会在它到达时停止。

不幸的是,如果不首先了解HTML的内部结构,就无法做到你想要的。考虑一下:

<div id="content">
  <div id="somethingelse">
  </div>
</div>

即使你可以构建一个匹配到</div>的正则表达式,你也无法构造一个匹配到正确</div>的正则表达式。您需要进行更密集的解析。

答案 2 :(得分:0)

使用解析器,而不是正则表达式。

这是一个PHP示例:http://htmlparsing.com/php.html

答案 3 :(得分:0)

这篇文章很棒,是满足我需求的完美解决方案!

它甚至适用于simpleXML或DOMDocument失败的html代码!

有时您必须解析由您无法控制的 第三方 生成的HTML代码,并且 不尊重任何dtd ,所以这里是递归的正则表达式。

我只是对你的代码添加了一些修改,并将它与PHP preg_match_all函数一起使用。

在下面的示例中,我们将尝试正确匹配 div #content

$content = <<<HTML
<div id="content">
    <!-- tutu -->
    <div id="something">
        <div id="somethingElse">
            <ul>
                <li>lorem 1</li>
                <li class="dfg" toto="titi">lorem 2</li>
                <li class="dfg">lorem 3</li>
                <li class="dfg">lorem 4</li>
                <li class="dfg">lorem 5</li>
                <li class="dfg">lorem 6</li>
            </ul>
            <br />
            <div id="emptyStuff"></div>
        </div>
    </div>
    <table>
        <tr>
            <td>cell 1</td>
            <td>cell 2</td>
            <td>cell 3</td>
            <td>cell 4</td>
            <td>cell 5</td>
            <td>cell 6</td>
        </tr>
        <tr>
            <td>cell 1</td>
            <td>cell 2</td>
            <td>cell 3</td>
            <td>cell 4</td>
            <td>cell 5</td>
            <td>cell 6</td>
        </tr>
    </table>
</div>
HTML;

$pattern = '@# match nested tag
(?(DEFINE)
    (?<comment>     <!--.*?-->)
    (?<cdata>       <![CDATA[.*?]]>)
    (?<empty>       <\w+[^>]*?/>)
    (?<inline>      <(script|style)[^>]+>.*?</\g{-1}>)
    (?<nested>      <(\w+)[^>]*(?<!/)>(?&innerHTML)</\g{-1}>)
    (?<unclosed>        <\w+[^>]*(?<!/)>)
    (?<text>        [^<]+)
)
(?<outerHTML><(?<tagName>div)\s?(?<attributes>[^>]*?id\h*=\h*(?<quote>"|\')[^(?&quote)\v>]*\bcontent\b[^(?&quote)\v>]*(?&quote)[^>]*)> # opening tag
(?<innerHTML>
    (?: (?&comment) | (?&cdata) | (?&empty) | (?&inline) | (?&nested) | (?&unclosed) | (?&text) )*
)
</(?&tagName)>) # closing tag
@six';

preg_match_all($pattern, $content, $matches);

var_dump(array_intersect_key($matches, array(
    'tagName' => 1,
    'attributes' => 1,
    'innerHTML' => 1,
    'outerHTML' => 1
)));

以下是输出

array(4) {
  ["outerHTML"]=>
  array(1) {
    [0]=>
    string(639) "<div id="content">
    <!-- tutu -->
    <div id="something">
        <div id="somethingElse">
            <ul>
                <li>lorem 1</li>
                <li class="dfg" toto="titi">lorem 2</li>
                <li class="dfg">lorem 3</li>
                <li class="dfg">lorem 4</li>
                <li class="dfg">lorem 5</li>
                <li class="dfg">lorem 6</li>
            </ul>
            <br />
            <div id="emptyStuff"></div>
        </div>
    </div>
    <table>
        <tr>
            <td>cell 1</td>
            <td>cell 2</td>
            <td>cell 3</td>
            <td>cell 4</td>
            <td>cell 5</td>
            <td>cell 6</td>
        </tr>
        <tr>
            <td>cell 1</td>
            <td>cell 2</td>
            <td>cell 3</td>
            <td>cell 4</td>
            <td>cell 5</td>
            <td>cell 6</td>
        </tr>
    </table>
</div>"
  }
  ["tagName"]=>
  array(1) {
    [0]=>
    string(3) "div"
  }
  ["attributes"]=>
  array(1) {
    [0]=>
    string(12) "id="content""
  }
  ["innerHTML"]=>
  array(1) {
    [0]=>
    string(615) "
    <!-- tutu -->
    <div id="something">
        <div id="somethingElse">
            <ul>
                <li>lorem 1</li>
                <li class="dfg" toto="titi">lorem 2</li>
                <li class="dfg">lorem 3</li>
                <li class="dfg">lorem 4</li>
                <li class="dfg">lorem 5</li>
                <li class="dfg">lorem 6</li>
            </ul>
            <br />
            <div id="emptyStuff"></div>
        </div>
    </div>
    <table>
        <tr>
            <td>cell 1</td>
            <td>cell 2</td>
            <td>cell 3</td>
            <td>cell 4</td>
            <td>cell 5</td>
            <td>cell 6</td>
        </tr>
        <tr>
            <td>cell 1</td>
            <td>cell 2</td>
            <td>cell 3</td>
            <td>cell 4</td>
            <td>cell 5</td>
            <td>cell 6</td>
        </tr>
    </table>
"
  }
}

我希望它会有所帮助!

答案 4 :(得分:-1)

<div id=content>.*?</div>

是你需要的 - 只要你没有嵌套的div。如果你有它们,请放弃并使用实际的XML解析器。

打开“dotall”选项(查看http://www.regular-expressions.info/dot.html,了解如何使用正则表达式进行操作)。

由您决定的细节。 : - )