-1
function emotify($text)
{
    $icons = array(
                ':)'    =>  '<img src="/images/emoticons/happy.png" alt="smile" class="icon_smile" />',
                ':-)'   =>  '<img src="/images/emoticons/happy.png" alt="smile" class="icon_smile" />',
                ':D'    =>  '<img src="/images/emoticons/grin.png" alt="smile" class="icon_laugh" />',
                ':d'    =>  '<img src="/images/emoticons/grin.png" alt="laugh" class="icon_laugh" />',
                ":'("    =>  '<img src="/images/emoticons/crying.png" alt="crying" class="icon_cry" />',
                ';('    =>  '<img src="/images/emoticons/crying.png" alt="crying" class="icon_cry" />',
                ':d'    =>  '<img src="/images/emoticons/grin.png" alt="laugh" class="icon_laugh" />',
                ';)'    =>  '<img src="/images/emoticons/wink.png" alt="wink" class="icon_wink" />',
                ':P'    =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
                ':-P'   =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
                ':-p'   =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
                ':p'    =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
                ':('    =>  '<img src="/images/emoticons/sad.png" alt="sad face" class="icon_sad" />',
                ':-('   =>  '<img src="/images/emoticons/sad.png" alt="sad face" class="icon_sad" />',
                ':o'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shock" />',
                ':O'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shock" />',
                ':0'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shack" />',
                ':|'    =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
                ':-|'   =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
                ':/'    =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
                ':-/'   =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />'
        );

     foreach($icons as $icon=>$image) {
      $icon = preg_quote($icon, '/');
$return = preg_replace("/$icon/i", $image, $text);
      }
    return $return;
}
$posted = emotify($posted);

this is my code to change emoticons into images. it just returns
Warning: preg_replace(): Unknown modifier '/' on line 203

how can I fix it? EDIT: this is all of my code including the array which may be the problem why my code is not working. I'm not sure, but non of the answers have helped so I think that must be were the problem lies.

user2166538
  • 313
  • 1
  • 3
  • 18
  • possible duplicate of [A better way to replace emoticons in PHP?](http://stackoverflow.com/questions/9658734/a-better-way-to-replace-emoticons-in-php) – Toto Sep 04 '13 at 11:19

5 Answers5

4

Having further established what you're doing through the comments, here is an answer using a DOM parser and a bit of cleverness:

$dom = new DOMDocument();
$dom->loadHTML($text);
$xpath = new DOMXPath($dom);
foreach($icons as $icon=>$image) {
  $textnodes = $xpath->query("//text()"); // get all text nodes
  foreach($textnodes as $node) {
    // the regex used here requires that there not be a non-space before it
    // in other words, it must be the first thing, or have a space before it
    while( preg_match("((?<!\S)".preg_quote($icon).")i",$node->nodeValue,$m,PREG_OFFSET_CAPTURE)) {
      $emote = $node->splitText($m[0][1]); // the offset is stored here
      $node = $emote->splitText(strlen($icon));
      // now replace the emote with the image:
      $img = $dom->createElement("img");
      $img->setAttribute("src",$image);
      // IMPORTANT: $image must be just the SRC, and NOT the entire HTML node
      $emote->parentNode->replaceChild($img,$emote);
    }
  }
}
// loadHTML puts the HTML into a document, we need to get it back out
$result = $dom->saveHTML($dom->getElementsByTagName('body')->item(0));
$result = substr($result,strlen("<body>"),-strlen("</body>"));

Now you may use $result, which all being well should have valid HTML including converted emotes.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
2

There is probably a slash in the value of $icon, so that you are actually calling

preg_replace( '/foo/bar/i', $image, $text )

which is a mistake.

Andy Lester
  • 91,102
  • 13
  • 100
  • 152
2

preg_quote will NOT escape slashes unless you tell it that this is your chosen delimiter.

That being said, using PREG is WAY overkill.

Use str_ireplace instead.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
2

preg_quote actually has 2 arguments. 2nd optional argument can be the regex delimiter to be used in preg functions.

As per the mannual:

delimiter

If the optional delimiter is specified, it will also be escaped. This is useful for escaping the delimiter that is required by the PCRE functions. The / is the most commonly used delimiter.

Use your code like this:

$icon = preg_quote($icon, '/');
$return = preg_replace("/$icon/i", $image, $text);

UPDATE: Problem is that you're not initializing $return variable before start of foreach loop and always trying to replace in original $text variable itself.

Have your foreach loop like this:

$return = $text;
foreach($icons as $icon=>$image) {
       $icon = preg_quote($icon, '/');
       $return = preg_replace("/$icon/i", $image, $return);
}
anubhava
  • 761,203
  • 64
  • 569
  • 643
1

You can do this:

function emotify($text)
{
    $icons = array(
        ':)'    =>  '<img src="/images/emoticons/happy.png" alt="smile" class="icon_smile" />',
        ':-)'   =>  '<img src="/images/emoticons/happy.png" alt="smile" class="icon_smile" />',
        ':D'    =>  '<img src="/images/emoticons/grin.png" alt="smile" class="icon_laugh" />',
        ':d'    =>  '<img src="/images/emoticons/grin.png" alt="laugh" class="icon_laugh" />',
        ':\'('  =>  '<img src="/images/emoticons/crying.png" alt="crying" class="icon_cry" />',
        ';('    =>  '<img src="/images/emoticons/crying.png" alt="crying" class="icon_cry" />',
        ';)'    =>  '<img src="/images/emoticons/wink.png" alt="wink" class="icon_wink" />',
        ':P'    =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
        ':-P'   =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
        ':-p'   =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
        ':p'    =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
        ':('    =>  '<img src="/images/emoticons/sad.png" alt="sad face" class="icon_sad" />',
        ':-('   =>  '<img src="/images/emoticons/sad.png" alt="sad face" class="icon_sad" />',
        ':o'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shock" />',
        ':O'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shock" />',
        ':0'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shack" />',
        ':|'    =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
        ':-|'   =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
        ':/'    =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
        ':-/'   =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />'
        );
    return str_replace(array_keys($icons), array_values($icons), $text);
}

Note that in this case it will be better to define two arrays.

Notice: this kind of search/replace must not be case-sensitive :D :d
A laughing emoticon was duplicate.

Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125