1

I have a string which contains multiple * to represent a show rating. As people may use an individual * to represent something other than a rating, if there are two or more together (e.g. **) I will assume that only these represent ratings.

I want to change each occurrence of * when it is in a rating to be ★ (& #9733;) to improve presentation.

I'm currently using preg_replace as follows to match when two or more occurrences of * are found

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

This, however, just places one ★ no matter how many occurrences. How can I modify this to replace each occurrence?

e.g. ** becomes ★★, *** becomes ★★★ etc.

0

2 Answers 2

4

You can use a custom callback for this and preg_replace_callback():

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

With an input string of *****, this will output:

★★★★★

For PHP < 5.3, you won't be able to use an anonymous function, so you'd have to declare the above callback as a standalone function. However, if you want to be super-ultra-cool, you can modify your regex to use assertions, and find all asterisks that come before or after one asterisk, like this:

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

The regex makes sure that from the current position, we either just saw an asterisk, or see two asterisks in front of us. If either of those assertions are true, we attempt to capture one asterisk.

This outputs:

replace these &#9733;&#9733;&#9733;&#9733;&#9733; not this* and &#9733;&#9733;&#9733; this &#9733;&#9733; &#9733;&#9733;&#9733;&#9733;
Sign up to request clarification or add additional context in comments.

Comments

0

You don't need to escape an asterisk inside a character class, cause it is seen as literal, however you must escape it outside:

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

The idea (since your limit is 2) is to replace one by one the * followed or preceded by an other *

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.