preg_match_all跳过一个嵌套标记

时间:2014-04-09 17:22:20

标签: preg-match

如果你看这个标签:

$text = '<div class="inner">
    <div class="left">
        <h4>text </h4>
        <p>Abdijstreet 42b<br>2000 city </p>
    </div>
    <div class="right">
        <span class="red">10:00 - 14:00</span>
    </div>
</div>'

我用它来preg_match:

preg_match_all("'<div class=\"inner\">(.*?)</div>'si", $text, $match);  // de ul tags

            $match[1] = array_splice($match[0], 0);

        foreach($match[1] as $val) // hele pagina
        {
                echo $val;
                }

我尝试了很多东西,但我只知道我需要什么,我做错了什么?

1 个答案:

答案 0 :(得分:0)

您是否想要在开始和结束div标签之间获取所有内容?如果是这样,那么你真的很接近。您只需从表达式中删除问号?即可。问号告诉脚本在找到REGEX中的下一个项目后停止匹配。在这种情况下,下一个项目是结束div标签。所以一旦找到它,它就会停止。如果你把它留下来,它将保持匹配,直到它击中它可以找到的最后一个div标签。

$text = '<div class="inner">
    <div class="left">
        <h4>text </h4>
        <p>Abdijstreet 42b<br>2000 city </p>
    </div>
    <div class="right">
        <span class="red">10:00 - 14:00</span>
    </div>
</div>';

preg_match_all("'<div class=\"inner\">(.*)</div>'si", $text, $match);

print "<pre><font color=red>"; print_r($match); print "</font></pre>";

如果您尝试提取div中的每个项目,那么您可能需要考虑使用DOM而不是REGEX来解决此问题。但是因为你使用了标签,所以它在REGEX:

preg_match_all('~<div class="(?!inner).*?>\K(.*?)(?=</div>)~ims', $text, $matches);

print "<PRE><FONT COLOR=BLUE>"; print_r($matches[1]); print "</FONT></PRE>";

这给你这个:

Array
(
    [0] => 
            <h4>text </h4>
            <p>Abdijstreet 42b<br>2000 city </p>

    [1] => 
            <span class="red">10:00 - 14:00</span>

)

REGEX的说明:

<div class="   (?!inner)   .*?   >   \K   (.*?)   (?=</div>)
      ^            ^        ^    ^    ^     ^          ^
      1            2        3    4    5     6          7
  1. <div class="查找文字开头div标记<div,后跟空格,后跟单词class,后跟等号,后跟引号。
  2. (?!inner)这是一个消极的预测(?!),可确保下一个字inner不会出现。
  3. .*?匹配任何一个字符.,零次或多次*,直到它碰到正则表达式?中的下一个项目。在这种情况下,它会在找到结束HTML括号后停止。
  4. >查找结束HTML括号。
  5. \K这告诉表达式忘记到目前为止匹配的所有内容,并从此处再次开始匹配。这基本上确保表达式的第一部分存在,但不存储它供我们使用。
  6. (.*?)与数字3相同,但我们在其周围使用括号(),以便我们可以捕获它并稍后使用它做一些事情。
  7. (?=</div>)这是一个积极的预测(?=),可确保结束div标签</div>出现在表达式的末尾,但不会捕获它。
  8. Here is a working demo of the code above