1

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

目前我有以下代码:

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

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

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

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

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

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

4

1 回答 1

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);

你可以从这个演示中看到这个输出:

Am I happy or sad today? 
于 2013-05-28T00:37:47.997 回答