Erik Edgren Erik Edgren - 1 month ago 10
PHP Question

Convert >< smiley to an image

I have the following regex for matching

><
:
/(\\\>\\\<)/
. But nothing happens when I use that regex.

How can I match
><
and turn it into an image?

If you need the whole function to see how I it looks like:

function bbcode($string) {

# GLOBAL
global $folder_smileys;

# VARIABLE
$hashtag = str_replace('|', '', $string);
$string = nl2br($string);
$icon_div_1 = '<div class="icon-inplace" style="background-image: url(';
$icon_div_2 = ');"></div>';


# ARRAY
$codes = Array(
'/\[b\](.+?)\[\/b\]/' => '<div class="font-bold">\1</div>',
'/\[i\](.+?)\[\/i\]/' => '<div class="font-italic">\1</div>',
'/\[s\](.+?)\[\/s\]/' => '<div class="font-strikethrough">\1</div>',
'/\[url=(.+?)\](.+?)\[\/url\]/' => '<a href="\1" target="_blank">\2</a>',

'/:\)/' => $icon_div_1 . url($folder_smileys.'smiley-1f642.png') . $icon_div_2,
'/;\)/' => $icon_div_1 . url($folder_smileys.'smiley-1f609.png') . $icon_div_2,
'/:\//' => $icon_div_1 . url($folder_smileys.'smiley-1f615.png') . $icon_div_2,
'/:\(/' => $icon_div_1 . url($folder_smileys.'smiley-1f641.png') . $icon_div_2,
'/:O/' => $icon_div_1 . url($folder_smileys.'smiley-1f632.png') . $icon_div_2,
'/:P/' => $icon_div_1 . url($folder_smileys.'smiley-1f61b.png') . $icon_div_2,
'/-.-/' => $icon_div_1 . url($folder_smileys.'smiley-1f611.png') . $icon_div_2,
'/\^\^/' => $icon_div_1 . url($folder_smileys.'smiley-1f604.png') . $icon_div_2,
'/:@/' => $icon_div_1 . url($folder_smileys.'smiley-1f621.png') . $icon_div_2,
'/<3/' => $icon_div_1 . url($folder_smileys.'symbol-2764.png') . $icon_div_2,
'/O.o/' => $icon_div_1 . url($folder_smileys.'smiley-1f924.png') . $icon_div_2,
'/\(Y\)/' => $icon_div_1 . url($folder_smileys.'symbol-1f44d-1f3fb.png') . $icon_div_2,
'/(\\\>\\\<)/' => $icon_div_1 . url($folder_smileys.'smiley-1f616.png') . $icon_div_2
);


# OUTPUT
return preg_replace(array_keys($codes), array_values($codes), $string);

}


echo bbcode('><'); // Outputs >< and not as an image

Answer

To be more clear:

function bbcode($string) {

    $smileys = [ ':)' => $icon_div_1 . url($folder_smileys. 'smiley-1f642.png') . $icon_div_2,
                 ';)' => $icon_div_1 . url($folder_smileys. 'smiley-1f649.png') . $icon_div_2,
                 // etc.
               ];

    $result = strtr($string, $smileys);

    $codes = [
        '~\[b](.+?)\[/b]~s' => '<div class="font-bold">\1</div>',
        '~\[i](.+?)\[/i]~s' => '<div class="font-italic">\1</div>',
        '~\[s](.+?)\[/s]~s' => '<div class="font-strikethrough">\1</div>',
        '~\[url=(.+?)](.+?)\[/url]~s' => '<a href="\1" target="_blank">\2</a>',
    ];

    $result = preg_replace(array_keys($codes), $codes, $result);

    return $result;
}

You need to replace the smileys first, otherwise the angle brackets produced by the bold, italic and url bbcodes risk to be overwritten.

You must understand that when you give an array to preg_replace (or to str_replace, the behaviour is the same), the function takes the first item, proceed to the replacements and produce a new string, then the next item uses this new string and proceeds to the next replacement. To illustrate this behaviour, if you write something like this:

$string = 'az';
$rep = [ '~a~' => 'z',
         '~z~' => 'a' ];

echo preg_replace(array_keys($rep), $rep, $string);

You will obtain "aa" (cause of the circular replacement: "az" -> "zz" -> "aa").

strtr behaves differently and parses the string only once (whatever the number of replacement pairs).

$string = 'az';
$rep = [ 'a' => 'z',
         'z' => 'a' ];

echo strtr($string, $rep);

It returns "za" (one pass).

Comments