php preg_replace在多个匹配时替换每个匹配项

时间:2013-06-22 23:21:51

标签: php regex

我有一个字符串,其中包含多个*来表示节目评分。 由于人们可能会使用个人*来表示评级以外的其他内容,如果有两个或更多个评分(例如**),我会假设只有这些代表评级。

我希望在评分为★(★)时更改*的每次出现,以改善演示。

我正在使用preg_replace,以便在找到两次或更多次*时进行匹配

$blurb = preg_replace("/[\*]{2,}/", "★", $s['longDescription']);

然而,这只是放置一个★,无论发生多少次。如何修改它以替换每次出现?

e.g。 **变为★★,***变为★★★等。

2 个答案:

答案 0 :(得分:4)

您可以使用自定义回调和preg_replace_callback()

$blurb = preg_replace_callback("/([\*]{2,})/", function( $match) { 
    return str_repeat( "★", strlen( $match[1])); }
, $s['longDescription']);

如果输入字符串为*****,则输出:

★★★★★

对于PHP< 5.3,您将无法使用匿名函数,因此您必须将上述回调声明为独立函数。但是,如果你想要超级酷,你可以修改你的正则表达式使用断言,并找到一个星号之前或之后的所有星号,如下所示:

$s['longDescription'] = 'replace these ***** not this* and *** this ** ****';
$blurb = preg_replace("/(?:(?<=\*)|(?=\*\*))\*/", "&#9733;", $s['longDescription']);

正则表达式确保从当前位置,我们要么只看到一个星号,要么看到我们面前的两个星号。如果其中任何一个断言都是真的,我们会尝试捕获一个星号。

outputs

replace these &#9733;&#9733;&#9733;&#9733;&#9733; not this* and &#9733;&#9733;&#9733; this &#9733;&#9733; &#9733;&#9733;&#9733;&#9733;

答案 1 :(得分:0)

您不需要在字符类中转义星号,因为它被视为文字,但您必须在外面将其转义:

$blurp = preg_replace('~(?<=\*)\*|\*(?=\*)~', '&#9733;', $yourString);

这个想法(因为你的限制是2)是逐个替换*后面或先前是另一个*