php非贪婪的正则表达式问题

时间:2009-05-14 13:01:05

标签: php regex non-greedy

演示:

$str = 'bcs >Hello >If see below!';
$repstr = preg_replace('/>[A-Z0-9].*?see below[^,\.<]*/','',$str);
echo $repstr;

我希望这个小程序输出的是“bcs&gt; Hello”,但事实上它只是“bcs”

我的模式出了什么问题?

3 个答案:

答案 0 :(得分:4)

我认为问题在于你误解了非贪婪量词的行为。一旦它运行,是的,它会比其它方式更早停止。但它不是意识到之前发生的事情(或者可能是以后出现的文本)。它只关心它的当前位置。因此,您发布的正则表达式将匹配以下所有内容:

">Hello >If see below!"

让我们看看它是如何工作的:

/>[A-Z0-9].*?see below[^,\.<]*/

正则表达式首先查找“&gt;”在“bcs&gt; Hello&gt;如果见下文!”中,找到第一个,即“Hello”之前的那个。好的,让我们检查表达式的下一部分:

[A-Z0-9]

下一个字符是H,它匹配模式[A-Z0-9]。还好!下一个:

.*?

现在我们匹配所有非换行符,直到我们到达第一个实例以匹配“见下面[^,。&lt;] *”的剩余表达式。如果我们只使用了一个简单的贪婪量词,我们可以匹配多个“见下面[^,。&lt;] *”的情况,直到我们匹配最后一个可能的情况。 (所以如果你的字符串继续存在,并且还有其他文本匹配该模式,那么它也会捕获它)非贪婪量词并不意味着你的整个模式将返回最小的可能匹配字符串中所有可能的匹配项。它只是规定了特定字符匹配的功能。

您可能希望尝试以下模式:

/>[A-Z0-9][^>]*?see below[^,\.<]*/

希望这可以解决它!

答案 1 :(得分:0)

你为什么不这样写:

$str = 'bcs >Hello >If see below!';
$repstr = preg_replace('/>If see below[^,\.<]*/','',$str);
echo $repstr;

答案 2 :(得分:0)

这可能是你所拥有的一个很好的选择。 你的正则表达式的问题在于,你不是选择你想要的东西,而是选择你不想要的东西,用空字符串替换它。 在我看来,最好的方法是选择你想要的东西,这就是下面的代码所做的。你最终得到的是第一个子模式匹配的内容,否则你会得到你的字符串。

$str = 'bcs >Hello >If see below!';
$repstr = preg_replace('/^([\w]+ >[\w]+).*?see below.*?$/i', '$1', $str);
var_dump($repstr);

我希望这会有所帮助。