我正在尝试解析一条可能包含表情符号的消息。可以接收的示例消息如下所示:
{"type":"chat","msg":"UserName:\u00a0\ud83d\ude0b \n"}
应该匹配的是 \u00a0 作为单个字符,和 \ud83d\ude0b 作为一对。
我有可以提取单个代码的正则表达式,但不能匹配完整的表情符号:
\\u[a-z0-9]{4}
有没有一种简洁的方法来解释一个句子中的任何/多个表情符号,以便我可以用我拥有的功能替换代理对?谢谢!
编辑:这是我将与正则表达式一起使用的函数
string ConvertToUnicode(string SurrogatePair)
{
string returnValue = "";
for (var i = 0; i < SurrogatePair.Length; i += char.IsSurrogatePair(SurrogatePair, i) ? 2 : 1)
{
var codepoint = char.ConvertToUtf32(SurrogatePair, i);
returnValue = String.Format("U+{0:X4}", codepoint);
}
return returnValue;
}
我有一个字典,其中键是 unicode,值是对表情符号图像的引用,因此我可以在 Unity UI 元素中显示它。
编辑2:
由于这个问题有点过于宽泛,我将具体说明我要完成的工作。我通过 websocket 连接从服务器接收 json 消息。此消息显示在 Unity 面板中,其中每条消息都是文本网格 pro text 对象。发送表情符号时,消息显示类似于上面的示例消息,唯一的变化是代理对根据发送的表情符号发生变化。为了将相应的表情符号图像正确插入到 text mesh pro 对象中,我需要获取指向正确表情符号的精灵图集 id。由于我没有手动将精灵插入图集中,而是从拼接的精灵表中读取它们,因此访问每个图像的唯一方法是通过它们的索引 id。要通过 id 正确识别图集中的表情符号,我创建了一个字典,按顺序插入 Unicode,因为它们作为键出现在精灵表中,其中值是图集中的索引。我现在要做的是使用正则表达式解析收到的表情符号消息,将此解析后的数据发送到我在上面发布的函数中以将其转换为 Unicode 值,然后从字典中检索正确的 id 以最终插入表情符号最初是在前端输入的。如果有更好的解决方法请告诉我,但根据我所做的研究,将图像插入 Unity 文本对象的唯一有效方法是我如何处理它。因此,我需要从消息中获取代理对。我现在要做的是使用正则表达式解析收到的表情符号消息,将此解析后的数据发送到我在上面发布的函数中以将其转换为 Unicode 值,然后从字典中检索正确的 id 以最终插入表情符号最初是在前端输入的。如果有更好的解决方法请告诉我,但根据我所做的研究,将图像插入 Unity 文本对象的唯一有效方法是我如何处理它。因此,我需要从消息中获取代理对。我现在要做的是使用正则表达式解析收到的表情符号消息,将此解析后的数据发送到我在上面发布的函数中以将其转换为 Unicode 值,然后从字典中检索正确的 id 以最终插入表情符号最初是在前端输入的。如果有更好的解决方法请告诉我,但根据我所做的研究,将图像插入 Unity 文本对象的唯一有效方法是我如何处理它。因此,我需要从消息中获取代理对。但从我所做的研究来看,将图像插入 Unity 文本对象的唯一有效方法是我如何处理它。因此,我需要从消息中获取代理对。但从我所做的研究来看,将图像插入 Unity 文本对象的唯一有效方法是我如何处理它。因此,我需要从消息中获取代理对。
编辑3:
如果其他人碰巧偶然发现了这个问题,我会留下我想出的从 html 网站获取表情符号的解决方案,通过 websocket 服务器进入 Unity textmeshpro。
这是一个 google 电子表格,其中包含十六进制值和我用来在 Unity 中创建字典/精灵图集的精灵表:https ://docs.google.com/spreadsheets/d/1XQY1n9cA1hx_PnsXoisxjanZRiQG0gd25VYEmk1W7mE/edit?usp=sharing 。
然后我使用了一个可以在这里找到的库:https ://github.com/aaronpk/emoji-detector-php
它可以解析字符串并找到表情符号。我用下面 sln 提供的正则表达式替换了使用的正则表达式,然后调整了主脚本以仅返回消息文本,但表情符号替换为包含在分隔符中的十六进制,我可以在 Unity 端使用正则表达式找到。
<?php
namespace Emoji;
define('LONGEST_EMOJI', 8);
function detect_emoji($string) {
// Find all the emoji in the input string
$prevencoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
$data = array();
$test = $string;
static $map;
if(!isset($map))
$map = _load_map();
static $regexp;
if(!isset($regexp))
$regexp = _load_regexp();
if(preg_match_all($regexp, $string, $matches)) {
foreach($matches[0] as $ch) {
$points = array();
for($i=0; $i<mb_strlen($ch); $i++) {
$points[] = strtoupper(dechex(uniord(mb_substr($ch, $i, 1))));
}
$hexstr = implode('-', $points);
$theMatch = $string.exec($ch);
$test = substr_replace($test, "[[[[".$hexstr."]]]]", strpos($test, $ch), strlen($ch));
}
}
if($prevencoding)
mb_internal_encoding($prevencoding);
return $test;
}
function _load_map() {
return json_decode(file_get_contents(dirname(__FILE__).'/map.json'), true);
}
function _load_regexp() {
return '/(?:' . json_decode(file_get_contents(dirname(__FILE__).'/regexp.json')) . ')/u';
}
function uniord($c) {
$ord0 = ord($c[0]); if ($ord0>=0 && $ord0<=127) return $ord0;
$ord1 = ord($c[1]); if ($ord0>=192 && $ord0<=223) return ($ord0-192)*64 + ($ord1-128);
$ord2 = ord($c[2]); if ($ord0>=224 && $ord0<=239) return ($ord0-224)*4096 + ($ord1-128)*64 + ($ord2-128);
$ord3 = ord($c[3]); if ($ord0>=240 && $ord0<=247) return ($ord0-240)*262144 + ($ord1-128)*4096 + ($ord2-128)*64 + ($ord3-128);
return false;
}
要在我的服务器脚本中调用它,我只需要添加:
include("src/Emoji.php");
在我的脚本顶部,并按如下方式调用该函数:
$message = Emoji\detect_emoji($message);
我确保这仅发送到我的 Unity 客户端,因为我将它们的 resourceId 存储在服务器代码中。
在 Unity 方面,为了找到需要替换的表情符号,我使用了:
string emojiPattern = @"(?<=\[\[\[\[).[^\]\]\]\]]*";
MatchCollection emojiMatch = Regex.Matches(messageString, emojiPattern);
for(int x = 0; x < emojiMatch.Count; x++)
{
messageString = messageString.Replace("[[[[" + emojiMatch[x].Value + "]]]]", "<sprite=" + emojiDictionary[emojiMatch[x].Value.ToLower()].ToString() + ">");
}
作为文本元素,我实例化的是一个文本网格专业文本 GUI 元素,它能够将它转换为我使用精灵表制作的精灵图集中的图像。希望这对将来的人有所帮助!