preg_match_all()中的正则表达式无法按预期工作

时间:2015-06-10 17:28:23

标签: php regex string preg-match-all

我有以下字符串:

"<h2>Define Vim is the greatest</h2> word processor, good <h3>Vi</h3>!".

我想用正则表达式选择h2h3,如下面的结构。

预期输出为:

array(
    0   =>  <h2>Define Vim is the greatviest</h2>
    1   =>  <h3>Vi</h3>
)

所以我实现我的正则表达式如下:

preg_match_all("/(?:<h2>|<h3>).*vi.*(?:<\/h2>|<\/h3>)/i", $input, $matches)

但不是如上所述的理想结果,它输出以下结果。

当前输出:

array(
    0 => <h2>Define Vim is the greatviest</h2> word prviocessor ever created <h3>Vi</h3>
)

如何更改我的代码/正则表达式,以便获得上面预期输出中的标记?

1 个答案:

答案 0 :(得分:2)

您的问题是,您首先错过delimiters for your regex而第二vi区分大小写,因此您必须添加i flag,以防不区分大小写。

所以你的代码看起来像这样(刚刚删除了正则表达式中的vi,现在我只抓取h1-6个标签之间的所有内容):

<?php

    $input = '"<h2>Define Vim is the greatest</h2> word processor, good <h3>Vi</h3>!".';

    preg_match_all("/(?:<h[0-6]>).*?(?:<\/h[0-6]>)/", $input, $matches);
    print_r($matches);

?>

输出:

Array
(
    [0] => Array
        (
            [0] => <h2>Define Vim is the greatest</h2>
            [1] => <h3>Vi</h3>
        )

)

修改

从你更新的正则表达式开始,你的问题是,.*是贪婪的,意味着它需要尽可能多。为了使它不贪婪,你必须在最后添加?。所以只需更改.* - &gt; .*?