在不升级 mysql 的情况下直接使用 mysql utf8 存储 超过三个字节的 emoji 表情
由于现在数据库的版本是5.5.2
,但是看网上说要直接存储emoji
表情,需要升级到5.5.3
然后把字符集设置为utf8mb4
,但是升级数据库感觉属于敏感操作。
考虑了多久之后直接考虑使用正则来替换,但是emoji
表情的unicode
码太多了,在网上找了一份代码,还是2年前更新的,想了想还是算了。
PHP 版本
最简单的办法就是直接找到接受到的文本中的字符串中4个字节的内容,做rawurlencode
编码,再入库。输出的时候再替换回来,然后再用rawurldecode
转码回unicode
到手机再解析为emoji
表情。
获取字符串长度mb_strlen
,按字符来截取字符串mb_substr
(mb_strcut
是按字节来截取,有区别)。
存储
$strEncode = '';
$length = mb_strlen($str,'utf-8');
for ($i=0; $i < $length; $i++) {
$_tmpStr = mb_substr($str,$i,1,'utf-8');
if(strlen($_tmpStr) >= 4){
$strEncode .= '[[EMOJI:'.rawurlencode($_tmpStr).']]';
}else{
$strEncode .= $_tmpStr;
}
}
echo $strEncode."\n";// 周梦康123~[[EMOJI:%F0%9F%98%81]][[EMOJI:%F0%9F%98%84]]
读取
//转码回去
$strDecode = preg_replace_callback("/\[\[EMOJI:(.*?)\]\]/", function($matches){
return rawurldecode($matches[1]);
}, $strEncode);
echo $strDecode."\n";
php 就这么轻松愉快的解决了。
Java 版本
考虑到想使用php里面的套路,对原字符串逐个字符获取其长度,如果超过3个字节,那么则编码下,就能存储了,依照上次的经验,我写了如下代码
String a = "\uD83D\uDE01";// 一个 emoji 表情
byte[] bytes = a.getBytes("utf-8");
System.out.println(bytes.length);// 输出 4
单个单个的来,能获取到正确的字节数,但是如何保证切割字符串的时候是正确的呢?我找遍了城市所有的街道,都没有,找到我要的方法.
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.UnsupportedEncodingException;
public class test{
public static void main(String[] args) throws Exception {
String content = args[0];
System.out.println(content);
int strLength = content.length();
String filterContent = emojiFilter(content);
System.out.println(filterContent);
String emojiStr = emojiRecovery(filterContent);
System.out.println(emojiStr);
}
private static String emojiFilter(String str){
String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(str);
StringBuffer sb = new StringBuffer();
while(matcher.find()) {
try {
matcher.appendReplacement(sb, "[[EMOJI:" + URLEncoder.encode(matcher.group(1),"UTF-8") + "]]");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
matcher.appendTail(sb);
return sb.toString();
}
private static String emojiRecovery(String str){
String patternString = "\\[\\[EMOJI:(.*?)\\]\\]";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(str);
StringBuffer sb = new StringBuffer();
while(matcher.find()) {
try {
matcher.appendReplacement(sb, URLDecoder.decode(matcher.group(1),"UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
matcher.appendTail(sb);
return sb.toString();
}
}
在不升级 mysql 的情况下直接使用 mysql utf8 存储 超过三个字节的 emoji 表情的更多相关文章
- mysql什么情况下会触发表锁
锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数 ...
- 在不重启MySQL的情况下用gdb工具设置变量
前提:此方法只是参考其它博客的一个记录,未经亲自验证 当在mysql客户端设置一些变量时提示如下报错: 于是想能否有办法在不重启的情况下设置这些只读变量,在网上搜索别人的博客后发现如下方法 1.命令行 ...
- 没有外网情况下linux安装mysql
首先linux要使用局域网 环境要求:局域网, windows系统, linux系统, mysql安装包mysql.tar.gz 注意:32位操作系统用32位安装包,64位系统用64位安装包,不 ...
- 【MySql】linux下,设置mysql表名忽略大小写
[障碍再现] 状况描述01: 在LINUX下调一个程序经常报出找不到表,但是我明明是建了表的, 测试的时候,遇到一些问题,从Windows平台访问虚拟机中的Web应用,经常报出找不到表 ...
- mysql学习-windows下绿色版mysql安装问题解决办法
1.下载绿色版mysql 从该地址http://dev.mysql.com/downloads/mysql/ 中选择windows的版本,选择下载. 2.将下载的压缩包解压. 3.将根目录下的my-d ...
- 【MySql】Linux下更改转移mysql数据库目录
1.关闭MySql: #service mysqld stop 2.转移数据: #cd /var/lib #ls #cp -a mysql /opt/mysql/ 3.修改配置文件,一下三个: ...
- c/c++使用VS2013连接MySQL与ubuntu下c链接mysql
vs连接数据库事实上就是将mysql数据库.h头文件接口.lib链接文件和dll运行文件增加到项目中.以下是配置怎样增加. 转于http://www.cnblogs.com/justinzhang/a ...
- mysql数据库字符集相关操作(修改表字段编码,使其支持emoji表情)
普通的UTF8编码是不支持emoji表情插入的,会报异常: Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x9 ...
- 【索引失效】什么情况下会引起MySQL索引失效
索引并不是时时都会生效的,比如以下几种情况,将导致索引失效: 1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因) 注意:要想使用or,又想让索引生效,只能将or条件 ...
随机推荐
- Nginx代理后服务端使用remote_addr获取真实IP
直奔主题,在代理服务器的Nginx配置(yourWebsite.conf)的location /中添加: #获取客户端IP proxy_set_header Host $host; proxy_set ...
- linux解压tar.gz
gnuzip或者tar -zxvf file.tar.gz unzip file.zip
- mybatis作用、基本使用、小结
1. MyBatis 1.1. 作用 MyBatis是持久层框架,它是支持JDBC的!简化了持久层开发! 使用MyBatis时,只需要通过接口指定数据操作的抽象方法,然后配置与之关联的SQL语句,即可 ...
- iTem2 保持连接,解决ssh的"Write failed: Broken pipe"问题
方法一: profiles -> sessions -> When idel, send ASCII code 问题场景 服务器环境:阿里云 Linux CentOS 主机 客户端:Mac ...
- 移动端实现上拉加载更多(使用dropload.js vs js)
做下笔记,:移动端实现上拉加载更多,其实是数据的分段加载,在这里为了做测试我写了几个json文件作为分段数据: 方式一:使用dropload.js; 配置好相关参数及回调函数就可使用:代码如下 var ...
- React之浅拷贝与深拷贝
最近发现的一个bug让我从react框架角度重新复习了一遍浅拷贝与深拷贝. 浅拷贝,就是两个变量都是指向一个地址,改变了一个变量,那另一个变量也随之改变.这就是浅拷贝带来的副作用,两个变量会相互影响到 ...
- VMware与Hyper-V
前段时间在Windows10上安装Hyper-V,使用docker时,提示要卸载VMware 今天重新安装VMware时,提示: 根据连接进去:https://kb.vmware.com/s/arti ...
- android开启线程的误区
发现一些刚学android的人,和我当初一样,对android的线程会存在着一定误区. 在android中,开启新线程时,一些人会用以下方法: new Handler().post(r); 但是这样并 ...
- HSQL结合润乾报表同步部署问题
1 . 问题概述 中国登记结算公司为了验证报表模型和附带的样例[内建的不算],都是需要连接携带的DEMO数据源才能够运行, 应用程序[润乾报表]需要部署到UNIX服务器上, DEMO自带的HSQ ...
- Evernote Markdown Sublime使用介绍
版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/4002619.html 这一篇博客继续探讨:Evernote ...