PHP - 用意义替换表情符号

时间:2013-05-28 00:26:52

标签: php regex preg-replace str-replace emoticons

我正在分析非正式聊天风格的消息以获取情绪和其他信息。我需要将所有表情符号替换为它们的实际含义,以便系统更容易解析消息。

目前我有以下代码:

$str = "Am I :) or :( today?";

$emoticons = array(
    ':)'    =>  'happy',
    ':]'    =>  'happy',
    ':('    =>  'sad',
    ':['    =>  'sad',
);

$str = str_replace(array_keys($emoticons), array_values($emoticons), $str);

这会直接替换字符串,因此如果表情符号被其他字符包围,则不会考虑。

如何使用正则表达式和preg_replace来确定它是否实际上是表情符号而不是字符串的一部分?

另外,我如何扩展我的数组,以便例如happy元素可以包含两个条目; :):]

1 个答案:

答案 0 :(得分:2)

为了可维护性和可读性,我会将您的表情符号数组更改为:

$emoticons = array(
    'happy' => array( ':)', ':]'),
    'sad'   => array( ':(', ':[')
);

然后,您可以像以前一样形成一个查找表,如下所示:

$emoticon_lookup = array();
foreach( $emoticons as $name => $values) {
    foreach( $values as $emoticon) {
        $emoticon_lookup[ $emoticon ] = $name;
    }
}

现在,您可以从表情符号查找数组动态形成正则表达式。请注意,此正则表达式需要围绕表情符号的非字边界,将其更改为您需要的内容。

$escaped_emoticons = array_map( 'preg_quote', array_keys( $emoticon_lookup), array_fill( 0, count( $emoticon_lookup), '/'));
$regex = '/\B(' . implode( '|', $escaped_emoticons) . ')\B/';

然后使用preg_replace_callback()和自定义回调来实现替换:

$str = preg_replace_callback( $regex, function( $match) use( $emoticon_lookup) {
    return $emoticon_lookup[ $match[1] ];
}, $str);

您可以从this demo看到此输出:

Am I happy or sad today?