最近公司业务上需要用到富文本表情的数据库存储和编解码。开始去网上抄了一个。由于不懂原理,正则表达式一知半解。导致仅仅代码因为粗心多了一个"\"就排查了很久bug。痛定思痛,学习了整个编解码的流程。分享给大家,望诸君少走弯路。
emoji编码
针对emoji表情来说,表情字符的长度为4. 可以利用此特点进行检索。编码流程为:遍历传入的字符串,找到len()=4的项,将其替换为"[\u"拼接上该字符的16进制的int型再拼接上"]",在golang中表示为
`[\u` + strconv.FormatInt(int64(rs[i]), 16) + `]`
用其替换原始字符串中该字符位置,其他位置字符保持不变。完整代码如下
func UnicodeEmojiCode(s string) string {
ret := ""
rs := []rune(s)
for i := 0; i < len(rs); i++ {
if len(string(rs[i])) == 4 {
u := `[\u` + strconv.FormatInt(int64(rs[i]), 16) + `]`
ret += u
} else {
ret += string(rs[i])
}
}
return ret
}
解码
解码过程为编码的逆过程,利用正则表达式获取到编码过的表情,去掉头部"[\u"和尾部"]",将中间部分还原成原始字符串即可。这里我们用以下正则来匹配编码好的表情
re := regexp.MustCompile("\\[[\\\\u0-9a-zA-Z]+\\]")
其中前两个\\表示转义,用来转义其后的"[","[\\\\u0-9a-zA-Z]+"表示匹配"\"或0-9之间的数字或大小写字母一至多次,"\\\\"表示匹配一个"\",贪婪匹配。而最后两个"\"依旧转义"]",我们还需要另一个正则去剔除其中的"[\u"和"]",如下
reg := regexp.MustCompile("\\[\\\\u|]")
其中的|表示匹配"|"两边任意一个正则,即"或"。解码代码如下
func UnicodeEmojiDecode(s string) string { //emoji表情的数据表达式 re := regexp.MustCompile("\\[[\\\\u0-9a-zA-Z]+\\]") //[u1f602] //提取emoji数据表达式 reg := regexp.MustCompile("\\[\\\\u|]") src := re.FindAllString(s, -1) for i := 0; i < len(src); i++ { e := reg.ReplaceAllString(src[i], "") p, err := strconv.ParseInt(e, 16, 32) if err == nil { s = strings.Replace(s, src[i], string(rune(p)), -1) } } return s }
笔者经验尚浅,如有错误,欢迎指正。