preg_replace的贪婪

时间:2011-12-23 08:55:57

标签: php regex preg-replace

echo preg_replace('/:*$/isD', ':', ':blue:');

一个相当简单的PHP正则表达式,旨在尽可能多地捕获字符串末尾的冒号(可能根本没有任何冒号),只用一个替换它。或者至少这就是我打算做的事情。

这是输出:

:blue::

我预计,因为preg_replace是贪婪的,所以字符串末尾的冒号会被捕获,因此我会得到

:blue:

代替。

奇怪的是,使用类似的代码检查字符串开头的冒号(即/^(:)*/isD)是否有效。我猜这与正则表达式从左到右搜索的事实有关,所以在字符串示例的非工作端,它只找到字符串的结尾,而在字符串示例的工作前面,它是已经找到了字符串的开头。

那就是说,我可以做些什么来使preg_replace捕获所有结束冒号?

2 个答案:

答案 0 :(得分:3)

echo preg_replace('/:+$/isD', ':', ':blue:');

只需将*(表示零或更多)替换为+(表示一个或多个)。

*首先匹配所有冒号直到结束,然后匹配空字符串,因此有两个匹配。

<强>更新

为确保最后只有一个冒号,您可以使用:

echo preg_replace('/^(.*?):*$/isD', '$1:', ':blue');

答案 1 :(得分:1)

尝试将*替换为+,以便空字符串不匹配:

echo preg_replace('/:+$/isD', ':', ':blue:');

产量

:blue:

<强>更新

考虑使用trim的变体,这会让它更“轻盈”:

echo rtrim(":blue:::::", ":") . ":";

这将从结尾删除所有:并根据需要添加一个: