2013-05-28 2 views
1

Я анализирую сообщение стиля неофициального чата для настроений и другой информации. Мне нужно, чтобы все смайлики заменялись их фактическим значением, чтобы облегчить систему синтаксическому анализу сообщения.PHP - Замена смайлика со значением

На данный момент у меня есть следующий код:

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

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

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

Это делает прямую замену строки, и, следовательно, не принимает во внимание, если смайлик окружен другими персонажами.

Как использовать регулярное выражение и preg_replace, чтобы определить, действительно ли он является смайликом, а не частью строки?

Также как я могу расширить свой массив так, чтобы, например, элемент happy мог содержать обе записи; :) и :]?

ответ

2

Для ремонтопригодности и читаемость, я хотел бы изменить свой массив смайликов, чтобы:

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

Затем вы можете сформировать справочную таблицу так же, как вы изначально были, как это:

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

Теперь вы можете динамически формировать регулярное выражение из массива lookicon. Обратите внимание, что для этого регулярного выражения требуется не-слово-граница, окружающая смайлик, измените его на то, что вам нужно.

$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?