1

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

我想将每个出现的 * 更改为 ★ (& #9733;) 以改进演示。

我目前正在使用 preg_replace 如下匹配当两个或多个 * 出现时

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

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

例如**变成★★,***变成★★★等。

4

2 回答 2

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']);

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

输出

replace these &#9733;&#9733;&#9733;&#9733;&#9733; not this* and &#9733;&#9733;&#9733; this &#9733;&#9733; &#9733;&#9733;&#9733;&#9733;
于 2013-06-22T23:26:23.033 回答
0

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

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

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

于 2013-06-22T23:33:06.833 回答