Piszę sobie małego shoutboxa i obecnie jestem na etapie konwersji emotek na tagi img. Stworzyłem sobie tablicę asocjacyjną, w której łatwo można podać co na co ma być zamienione (emota -> nazwa grafiki), wygląda to tak:

$Emoty = array(':)' => 'smiley', ';(' => 'smiley-cry', ':>' => 'smiley-evil');

Następnie rozbijam to na dwie tabelki:

  foreach ($Emoty as $From => $To){
        $EmoteFrom[] = sprintf($RegEmote, preg_quote($From));
        $EmoteTo[] = sprintf(' <img src="gfx/%s.png" alt="%s" title="%s" /> ', $To, $From, $From);
  }

Kod emotki wyszukiwany jest wyrażeniem regularnym, które wygląda tak:

$RegEmote = "~(^|\s)%s($|\s)~";

Pozwala to wyłapać tylko te emotki, które są na początku stringa lub poprzedzone spacją oraz są na końcu stringa lub zakończone spacją. Nie wrzucają się dzięki temu w np. linki lub inne zapisy. Ostatecznie zamiana wygląda tak:

$Text = preg_replace($EmoteFrom, $EmoteTo, $Text);

Wszystko działa tip top, ale problem jest z emotkami zawierającymi ">" czy też "<", w ogóle ich nie łapie. Co dziwniejsze to kilka testerów regexp online, które sprawdzałem to działają bez problemu na tych znakach.

Czy ktoś może zna przyczynę, dlaczego PHP nie łapie tego?

Dopisek: Ok, walnąłem gafę - zaplątało mi się htmlspecialchars wcześniej i konwertowało > na > itp. Sh*t happens :D .