Maj. Fail
Maj. Fail

Reputation: 67

Complex PHP/Perl regular expression for emoticons

I've checked google for help on this subject but all the answers keep overlooking a fatal flaw in the replacement method.

Essentially I have a set of emoticons such as :) LocK :eek and so on and need to replace them with image tags. The problem I'm having is identifying that a particular emoticon is not part of a word and is alone on a line. For example on our site we allow 'quick links' which are not included in the smiley replacement which take the format go:forum, user:Username and so on. Pretty much all answers I've read don't allow for this possiblity and as such break these links (i.e. go<img src="image.gif" />orum). I've tried experimenting around with different ways to get around this to check for the start of the line, spaces/newline characters and so on but I've not had much luck.

Any help with this problem would be greatly appreciated. Oh also I'm using PHP 5 and the preg_% functions.

Thanks, Rupert S.

Edit 18/04/2011:

Thanks for your help peeps :) Have created the final regex that I though I'd share with everyone, had a couple problems to do with special space chars including newline but it's now working like a dream the final regex is:

(?<=\s|\A|\n|\r|\t|\v|\<br \/\>|\<br\>)(:S)(?=\s|\Z|$|\n|\r|\t|\v|\<br \/\>|\<br\>)

Upvotes: 3

Views: 682

Answers (2)

mario
mario

Reputation: 145512

To complete the comment into an answer: The simplest workaround would be to assert that the emoticons are always surrounded by whitespace.

 (?<=\s|^)[<:-}]+(?=\s|$)

The \s covers normal spaces and line breaks. Just to be safe ^ and $ cover occurrences at the start or very end of the text subject. The assertions themselves do not match, so can be ignored in the replacement string/callback.

Upvotes: 4

ANisus
ANisus

Reputation: 78075

If you want to do all the replace in one single preg_replace, try this:

preg_replace('/(?<=^|\s)(:\)|:eek)(?=$|\s)/e'
    ,"'$1'==':)'?'<img src=\"smile.gif\"/>':('$1'==':eek'?'<img src=\"eek.gif\"/>':'$1')"
    ,$input);

Upvotes: 3

Related Questions