文档章节

mysql保存emoji表情问题-java

泡腾片
 泡腾片
发布于 2017/09/05 08:50
字数 641
阅读 49
收藏 0

问题

无法保存emoji表情到MySQL(字符集为utf-8)?

原因

emoji表情也是utf-8编码,但是占用4个字节,而mysql的utf-8字符集的数据库每个字符只有3个字节,所以无法保存emoji表情到mysql数据库。

解决方法

一、修改数据库字符集为utf8mb4

在5.5.3版本之后的mysql数据库支持utf8mb4字符集,可以保存4个字节的emoji表情。需要修改数据库、表、字段的字符集为utf8mb4。

这是最简单有效的方法。

二、将emoji表情转换成可以保存的格式

我试过的有两种方式,一种是以urlencode转换,一种是以base64加密,都是可以将emoji表情保存为mysql数据库(utf-8)的方法,但也有很明显的缺陷:

(1)每次输入和输出都要进行加密和解密,会影响效率,虽然影响不大

(2)一个emoji表情,正常情况下只用一个字符就能保存,但urlencode处理后需要12字节(%03%25%17%37的格式),base64需要6字节(8J-Sjg的格式),除此之外还需正则识别的标志,比如[[8J-Sjg]],其中[[]]是为了正则表达式定位用的。另注意:若处理json格式的字符串,最好不要用[[]],可能保存数据库中的结果变成[["8J-Sjg"]]。

emoji表情的正则表达式

发现一个很不错的正则,实验后善未发现无法识别的表情(iOS ipad上实验)

input.replaceAll("[\\x{10000}-\\x{10ffff}\ud800-\udfff]", "");

 

来源:http://stackoverflow.com/questions/27820971/why-a-surrogate-java-regexp-finds-hypen-minus

 

样例

 

[java] view plain copy

print?

  1.  /** 
  2.  * @Description 将字符串中的emoji表情转换成可以在utf-8字符集数据库中保存的格式(表情占4个字节,需要utf8mb4字符集) 
  3.  * @param str 
  4.  *            待转换字符串 
  5.  * @return 转换后字符串 
  6.  * @throws UnsupportedEncodingException 
  7.  *             exception 
  8.  */  
  9. public static String emojiConvert1(String str)  
  10.         throws UnsupportedEncodingException {  
  11.     String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";  
  12.   
  13.     Pattern pattern = Pattern.compile(patternString);  
  14.     Matcher matcher = pattern.matcher(str);  
  15.     StringBuffer sb = new StringBuffer();  
  16.     while(matcher.find()) {  
  17.         try {  
  18.             matcher.appendReplacement(  
  19.                     sb,  
  20.                     "[["  
  21.                             + URLEncoder.encode(matcher.group(1),  
  22.                                     "UTF-8") + "]]");  
  23.         } catch(UnsupportedEncodingException e) {  
  24.             LOG.error("emojiConvert error", e);  
  25.             throw e;  
  26.         }  
  27.     }  
  28.     matcher.appendTail(sb);  
  29.     LOG.debug("emojiConvert " + str + " to " + sb.toString()  
  30.             + ", len:" + sb.length());  
  31.     return sb.toString();  
  32. }  
  33.   
  34. /** 
  35.  * @Description 还原utf8数据库中保存的含转换后emoji表情的字符串 
  36.  * @param str 
  37.  *            转换后的字符串 
  38.  * @return 转换前的字符串 
  39.  * @throws UnsupportedEncodingException 
  40.  *             exception 
  41.  */  
  42. public static String emojiRecovery2(String str)  
  43.         throws UnsupportedEncodingException {  
  44.     String patternString = "\\[\\[(.*?)\\]\\]";  
  45.   
  46.     Pattern pattern = Pattern.compile(patternString);  
  47.     Matcher matcher = pattern.matcher(str);  
  48.   
  49.     StringBuffer sb = new StringBuffer();  
  50.     while(matcher.find()) {  
  51.         try {  
  52.             matcher.appendReplacement(sb,  
  53.                     URLDecoder.decode(matcher.group(1), "UTF-8"));  
  54.         } catch(UnsupportedEncodingException e) {  
  55.             LOG.error("emojiRecovery error", e);  
  56.             throw e;  
  57.         }  
  58.     }  
  59.     matcher.appendTail(sb);  
  60.     LOG.debug("emojiRecovery " + str + " to " + sb.toString());  
  61.     return sb.toString();  
  62. }  

本文转载自:http://blog.csdn.net/a601025382s/article/details/50915286

泡腾片
粉丝 0
博文 25
码字总数 12012
作品 0
普陀
高级程序员
私信 提问
关于Druid连接mysql的乱码问题(utf8mb4)

在开发过程中需要爬取一些数据,其中包含emoji表情,所以需要使用utf8mb4进行数据库的连接,在开发环境我自行搭建的mysql服务没有出现问题。 但在生产环境使用的是AWS的云服务,则不能正常连...

SethOS
2017/08/11
645
1
微信nickname乱码(emoji)及mysql编码格式设置(utf8mb4)解决的过程

网上的解决办法大多是修改my.cnf参数,设置mysql的编码为utf8mb4,这种方法虽然彻底,但是通常要重启mysql,会造成生产系统临时当机。我认为写的比较好的方法是:mysql/Java服务端对emoji的支...

Jack088
05/16
0
0
MySQL 解决 emoji表情 的方法,使用utf8mb4 字符集(4字节 UTF-8 Unicode 编码)

一、基本原则 如果要实现存储 emoji 表情到 MySQL 实例,需要应用客户端、到 MySQL 实例的连接、MySQL 实例内部 3 个方面统一使用或者支持 utf8mb4 字符集。 注:关于 utf8mb4 字符集,请参考...

xiaomin0322
06/19
0
0
过滤字符串中的Emoji表情[转]

iOS 5.0之前,苹果都是采用3个字节来承接 emoji 表情,Java 的普通 char 可以支持显示。但 iOS 5.0 之后, 苹果升级了系统自带的 emoji 表情输入法,用的 Unicode 6 标准来统一,是采用4个 ...

彭博
2013/04/08
40.3K
8
不要在MySQL中使用utf8,改用utf8mb4

mysql官网对字符集的说明:https://dev.mysql.com/doc/refman/8.0/en/charset-unicode.html 一、为什么需要使用utf8mb4。 在mysql、MariaDB中: MySQL的“utf8mb4”是真正的“UTF-8”。长度是...

王坤charlie
05/15
0
3

没有更多内容

加载失败,请刷新页面

加载更多

vmstat命令详解

https://www.cnblogs.com/ggjucheng/archive/2012/01/05/2312625.html

流光韶逝
20分钟前
0
0
如何理解算法时间复杂度的表示

先从O(1) 来说,理论上哈希表就是O(1)。因为哈希表是通过哈希函数来映射的,所以拿到一个关键 字,用哈希函数转换一下,就可以直接从表中取出对应的值。和现存数据有多少毫无关系,故而每次执...

yky20190625
36分钟前
2
0
分布式架构 实现分布式锁的常见方式

一、我们为什么需要分布式锁? 在单机时代,虽然不需要分布式锁,但也面临过类似的问题,只不过在单机的情况下,如果有多个线程要同时访问某个共享资源的时候,我们可以采用线程间加锁的机制...

太猪-YJ
今天
7
0
GitLab Docker 安装记录

安装环境 环境Centos7.4 64 1.拉取镜像文件 docker pull gitlab/gitlab-ce:latest 2.docker 安装 git.zddts.com 为访问域名或换成可以访问的IP docker run -d --hostname git.***.com -p ......

侠者圣
今天
0
0
EfficientNet: 再论 CNN 的网络规模

由于这里公式无法正常显示,所有内容以图片内容上传,如有需要,可提供 pdf 版。

爱吃草莓的皮卡丘
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部