-1

Possible Duplicate:
Replace a list of emoticons with their images

i'm developing a website where i want to give users possibility to put smiles on posts. My (just functional) idea is to use array in this way:

$emoticons = array(
array("17.gif",":)"),
array("6.jpg",":P"),
.....
array("9.jpg",":'("),
array("5.gif","X)")
);

with image on [0] and emoticon on [1]. And on each $post:

foreach($emoticons as $emoticon){
     $quoted_emoticon = preg_quote($emoticon[1],"#");
     $match = '#(?!<\w)(' . $quoted_emoticon .')(?!\w)#';
     $post = preg_replace($match,'<img src="images/emoticons/'.$emoticon[0].'">',$post);
}

This is working good, but my problem is '#(?!<\w)(' and ')(?!\w)#' because I want emoticons to apply only when preceding characters are "begin" (^) or "blank" and succeeding characters are "end" ($) or "blank". What is the right regex to do this?

Community
  • 1
  • 1
Giuseppe Donato
  • 157
  • 2
  • 15

2 Answers2

1

I think you want the positive look behind and positive look ahead.

Example:

(?<=\s|^)(\:\))(?=\s|$)

Your example updated:

foreach($emoticons as $emoticon){
     $quoted_emoticon = preg_quote($emoticon[1],"#");
     $match = '(?<=\s|^)(' . $quoted_emoticon .')(?=\s|$)';
     $post = preg_replace($match,'<img src="images/emoticons/'.$emoticon[0].'">',$post);
}
Brian
  • 4,974
  • 2
  • 28
  • 30
  • Better... but not perfect, because the first occurance does not work. At the begin, if the $post is only :) it does not work! – Giuseppe Donato Jun 24 '12 at 17:33
  • I changed in this way: $match = '#(?<=\s|$)(' . $quoted_emoticon .')(?=\s|$)#'; – Giuseppe Donato Jun 24 '12 at 17:34
  • infact it's this: $match = '#(?<=\s|^)(' . $quoted_emoticon .')(?=\s|$)#'; – Giuseppe Donato Jun 24 '12 at 17:35
  • Sorry, a lazy copy paste error. I updated my expression. – Brian Jun 24 '12 at 17:36
  • @GiuseppeDonato - This answer works for you? Look at http://ideone.com/vhBar - Am I missing something? – Ωmega Jun 24 '12 at 18:01
  • I think you could use `(?<!\b)`...`(?!\b)` as a shorter equivalent, if you want to. – Justin Morgan - On strike Jun 24 '12 at 20:40
  • @user1215106, no I didn't test the code, I added it to the OP's example so he could see the difference. I'm sure the OP can figure out any syntax issues. My expression, however, fits the OP's needs "exactly". – Brian Jun 24 '12 at 22:53
  • @used2could - it is not about syntax, but about not escaping content of emotion string - it does not work - test it. – Ωmega Jun 24 '12 at 22:59
  • @user1215106, The pattern I listed works http://regexr.com?31c2u, I don't care about the modified PHP snippet fully working. It was only written for a little more context of the positive look behind and ahead in his work. Like I said, the OP can figure out the rest. – Brian Jun 26 '12 at 13:24
0

I would go with:

$e = array( ':)' => '1.gif',
            ':(' => '2.gif',
          );

foreach ($e as $sign => $file) { 
  $sign = preg_replace('/(.)/', "\\$1", $sign); 
  $pattern = "/(?<=\s|^)$sign(?=\s|$)/";
  $post = preg_replace($pattern, " <img src=\"images/emoticons/$file\">", $post);  
} 
Ωmega
  • 42,614
  • 34
  • 134
  • 203
  • No, you didn't understand or i was not able to explain the problem: I want to apply replace ONLY when preceding/succeeding char is BLANK (or they are ^|$, that means begin/end) My data structure already work! I have no problem replacing... i want to limit WHEN to replace! – Giuseppe Donato Jun 24 '12 at 17:22
  • if someone write: Hello, my name is Ralph ;-) OK. If some write: Hello, my name is Ralph;-) NO Understand? – Giuseppe Donato Jun 24 '12 at 17:24