0

演示:

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

我希望这个小程序输出的是“bcs >Hello”,但实际上它只是“bcs”

我的模式有什么问题?

4

3 回答 3

4

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

">Hello >If see below!"

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

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

正则表达式首先在“bcs >Hello >If see below!”中查找“>”,然后找到第一个,即“Hello”之前的那个。好的,让我们检查表达式的下一部分:

[A-Z0-9]

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

.*?

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

您可能想尝试以下模式:

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

希望这可以清除它!

于 2009-05-14T16:33:27.437 回答
0

你为什么不这样写:

$str = 'bcs >Hello >If see below!';
$repstr = preg_replace('/>If see below[^,\.<]*/','',$str);
echo $repstr;
于 2009-05-14T13:43:55.673 回答
0

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

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

我希望这有帮助。

于 2009-05-14T13:59:03.423 回答