Kevin
Kevin

Reputation: 512

PHP Regex to strip excess punctuation

So basically we need a regex to strip excess punctuation from a string, leaving only one of the punctuation characters.

So:

This is my awesome string!!!!! Don't you love it???!!??!!

Would result in

This is my awesome string! Don't you love it?!

I have tried and tried and tried to get this, but I either end up mangling the string or it doesn't work at all. I'm still learning Regexes so please forgive what is surely a stupid question.

I guess "punctuation" would be pretty much anything that's not A-Za-z0-9

Edit It appears that I misunderstood our original requirements. Using the accepted solution below, how would I adjust it so that no matter what characters you have, the punctuation is limited to the first only?

IE

???!!!!!!

would become just

?

And

This is my string!!!?!?!?!? Isn't it great???!?!?!!

would become

This is my string! Isn't it great?

Upvotes: 4

Views: 155

Answers (3)

Gareth
Gareth

Reputation: 5718

Similar to the other answers, but should take care of any non 0-9a-zA-Z characters in any order leaving you with one of each left:

$newstring= preg_replace('/([^\w\s])(?=[^\w\s]*\1)/', '', $oldstring);

Should turn

This is my awesome string!!!!! Don't you love it???!!??!!

into

This is my awesome string! Don't you love it?!

It works by using a positive lookahead to see if the character appears again in this string of punctuation. If it does, it's replaced with the empty string.

Upvotes: 4

raina77ow
raina77ow

Reputation: 106483

Something like preg_replace('#([!?])\1+#', '$1'), perhaps? For example:

$t = 'This is my awesome string!!!!! Don\'t you love it???!!??!!';
$u = preg_replace('#([!?])\1+#', '$1', $t);

// to clear out all these '?!?!...' and '!?!?...' sequences.
$u = preg_replace('#(\?!|!\?)\1+#', '$1', $u); 


echo $u; // This is my awesome string! Don't you love it?!

Upvotes: 0

Ry-
Ry-

Reputation: 225281

Try preg_replace_callback:

preg_replace_callback('/[!?]+/', function($m) {
    $excl = strpos($m[0], '!');
    $ques = strpos($m[0], '?');

    if($excl !== false && $excl <= $ques) {
        return $ques === false ? '!' : '!?';
    } else {
        return $excl === false ? '?' : '?!';
    }
}, $str);

Here's a demo.

Upvotes: 0

Related Questions