表情符号替换-PHP


Emoticon Replacement - PHP

我需要将文本表情符号替换为html图像标记。我整理了以下数据:

private $smile = array(">:]", ":-)", ":)", ":o)", ":]", ":3", ":c)", ":>", "=]", "8)", "=)", ":}", ":^)");
private $laugh = array(">:D", ":-D", ":D", "8-D", "x-D", "X-D", "=-D", "=D", "=-3", "8-)");
private $sad = array(">:[", ":-(", ":(",  ":-c", ":c", ":-<", ":-[", ":[", ":{", ">.>", "<.<", ">.<");
private $wink = array(">;]", ";-)", ";)", "*-)", "*)", ";-]", ";]", ";D", ";^)");
private $tongue = array(">:P", ":-P", ":P", "X-P", "x-p", ":-p", ":p", "=p", ":-Þ", ":Þ", ":-b", ":b", "=p", "=P");
private $surprise = array(">:o", ">:O", ":-O", ":O", "°o°", "°O°", ":O", "o_O", "o.O", "8-0");
private $annoyed = array(">:''", ">:/", ":-/", ":-.", ":''", "=/", "=''", ":S");
private $cry = array(":'(", ";'(");
private $t_smile = "<img class='"smiley'" src='"/images/emoticons/smile.png'"/>";
private $t_laugh = "<img class='"smiley'" src='"/images/emoticons/laugh.png'"/>";
private $t_sad = "<img class='"smiley'" src='"/images/emoticons/sad.png'"/>";
private $t_wink = "<img class='"smiley'" src='"/images/emoticons/wink.png'"/>";
private $t_tongue = "<img class='"smiley'" src='"/images/emoticons/tongue.png'"/>";
private $t_surprise = "<img class='"smiley'" src='"/images/emoticons/surprise.png'"/>";
private $t_annoyed = "<img class='"smiley'" src='"/images/emoticons/annoyed.png'"/>";
private $t_cry = "<img class='"smiley'" src='"/images/emoticons/cry.png'"/>"

我目前只是在做一个例子:

$str = str_replace($this->laugh, $this->t_laugh, $str);

对于每组。它工作得很好,但我只需要在单词没有被字母或其他数字包围的情况下进行替换。换句话说,我需要编译一个包含每个表情符号数组的regex,这样我就可以使用preg_replace而不是str_replace。有没有一种方法可以很容易地做到这一点,而不是硬编码正则表达式并转义所有必要的字符?

编辑:

此外,我需要匹配并替换出现在字符串开头和结尾的表情符号,因此使用空格技术进行简单填充是不够的。

编辑2:

我以Mark为例,使用preg_quote将数组中的regex预编译为:

private $smile = "#(^|'W)('>':']|':-')|':')|':o')|':']|':3|':c')|':'>|'=']|8')|'=')|':'}|':'^'))($|'W)#";
private $laugh = "#(^|'W)('>':D|':-D|':D|8-D|x-D|X-D|'=-D|'=D|'=-3|8-')|xD|XD|8D|'=3)($|'W)#";
private $sad = "#(^|'W)('>':'[|':-'(|':'(|':-c|':c|':-'<|':-'[|':'[|':'{|'>'.'>|'<'.'<|'>'.'<)($|'W)#";
private $wink = "#(^|'W)('>;']|;-')|;')|'*-')|'*')|;-']|;']|;D|;'^'))($|'W)#";
private $tongue = "#(^|'W)('>':P|':-P|':P|X-P|x-p|':-p|':p|'=p|':-Þ|':Þ|':-b|':b|'=p|'=P|xp|XP|xP|Xp)($|'W)#";
private $surprise = "#(^|'W)('>':o|'>':O|':-O|':O|°o°|°O°|':O|o_O|o'.O|8-0)($|'W)#";
private $annoyed = "#(^|'W)('>':''|'>':/|':-/|':-'.|':''|'=/|'=''|':S|':'/)($|'W)#";
private $cry = "#(^|'W)(':''(|;''()($|'W)#";

与preg_replace完美配合!

如果您想使用正则表达式:

$pat = '#(^|'W)'.preg_quote($this->laugh,'#').'($|'W)#';
$str = str_replace($pat, $this->t_laugh, $str);

这基本上意味着表情符号可以在字符串的开头,也可以由非单词字符进行处理,并且后面必须是字符串的末尾或另一个非单词字符。preg_quote是必要的,以防您的表情符号包含任何特殊的正则表达式字符。

此外,更好的格式可能是:

$emoticons = array(
    'smile' => array('<img src...', array('>:]',':-)',...),
    'laugh' => array('<img src....', array(...)),
    ...
)

然后你可以循环浏览所有内容。


更新

应该使用否定的环视来匹配并排的表情符号。然后它就不会尝试与周围的空间相匹配。

<?php
$smile = array(">:]", ":-)", ":)", ":o)", ":]", ":3", ":c)", ":>", "=]", "8)", "=)", ":}", ":^)");
$laugh = array(">:D", ":-D", ":D", "8-D", "x-D", "X-D", "=-D", "=D", "=-3", "8-)");
$sad = array(">:[", ":-(", ":(",  ":-c", ":c", ":-<", ":-[", ":[", ":{", ">.>", "<.<", ">.<");
$wink = array(">;]", ";-)", ";)", "*-)", "*)", ";-]", ";]", ";D", ";^)");
$tongue = array(">:P", ":-P", ":P", "X-P", "x-p", ":-p", ":p", "=p", ":-Ã", ":Ã", ":-b", ":b", "=p", "=P");
$surprise = array(">:o", ">:O", ":-O", ":O", "°o°", "°O°", ":O", "o_O", "o.O", "8-0");
$annoyed = array(">:''", ">:/", ":-/", ":-.", ":''", "=/", "=''", ":S");
$cry = array(":'(", ";'(");
$ary = array_merge($smile, $laugh, $sad, $wink, $tongue,$surprise,$annoyed,$cry);
foreach ($ary as $a)
{
        $quoted[] = preg_quote($a, '#');
}
$regex = implode('|', $quoted);

$full = '#(?!<'w)(' . $regex .')(?!'w)#';
echo $full.PHP_EOL;
$str = "Testing :) emoticons :D :(";
preg_match_all($full, $str, $matches);
print_r($matches[0]);

此外,在编写regex模式时,请尝试使用单引号,因为双引号允许转义序列,而单引号不会解释转义序列。也就是说,当使用双引号时,有时需要将斜杠加倍。

可能有一个类似的格式化循环

for($i=0;$i<count($smiles);++$i){
   $smiles[$i]="~'s".$smiles[$i]."'s~";
}

那么它只是preg_replace($smiles,$t_smiles,$text)的一个小部分

您可能正在寻找以下内容:

function toRegex(array $emotes) {
    foreach ($emotes as &$emote)
        $emote = preg_quote($emote, "/");
    return "/'b" . implode($emotes, "'b|'b") . "'b/";
}
$imaged = preg_replace(toRegex($smiles), $t_smiles);

此外,正如马克所提到的,你最好使用一个庞大的所有表情符号数组,而不是手动处理一百个小变量。