Design issue Prevent smileys/emojis to be replaced within words

Affected version

Chris D

XenForo developer
Staff member
This is really a long standing design issue for witch there is no ideal solution.

It’s not quite as simple as checking for word boundaries as that would also prevent adjacent smilies like :):)

Technically it may prevent this smilie working too [b]:) hello[/b] :) hello.

As ever, there are ways to escape the smilie creation and other BB code. Last time we had this reported it was the potentially vague and relatively unknown PLAIN BB code, but at least now we have ICODE.


Well-known member
It should work if XenForo only adds the word boundary delimiter where it's actually needed:
--- a/src/XF/Str/Formatter.php
+++ b/src/XF/Str/Formatter.php
@@ -175,7 +175,15 @@ class Formatter
         if ($this->smilieTranslate)
-            $text = strtr($text, $this->smilieTranslate);
+            $pattern = '/(' . implode('|', array_map(function($str) {
+                $prefix = ctype_alnum($str[0]) ? '\b' : '';
+                $suffix = ctype_alnum($str[-1]) ? '\b' : '';
+                return $prefix . preg_quote($str, '/') . $suffix;
+            }, array_keys($this->smilieTranslate))) . ')/';
+            $text = preg_replace_callback($pattern, function($m) {
+                return $this->smilieTranslate[$m[1]];
+            }, $text);
         if ($escapeCallback)
(Would probably be a good idea to cache the pattern for performance reasons, but it seems to handle all mentioned cases.)

Chris D

XenForo developer
Staff member
It’s not something we’re looking to do right now though appreciate the effort.

Perhaps documenting your suggestion in the suggestion forum is worthwhile so we can consider it in the future?