zoukankan      html  css  js  c++  java
  • 在不升级 mysql 的情况下直接使用 mysql utf8 存储 超过三个字节的 emoji 表情

    由于现在数据库的版本是5.5.2,但是看网上说要直接存储emoji表情,需要升级到5.5.3然后把字符集设置为utf8mb4,但是升级数据库感觉属于敏感操作。

    考虑了多久之后直接考虑使用正则来替换,但是emoji表情的unicode码太多了,在网上找了一份代码,还是2年前更新的,想了想还是算了。

    PHP 版本

    最简单的办法就是直接找到接受到的文本中的字符串中4个字节的内容,做rawurlencode编码,再入库。输出的时候再替换回来,然后再用rawurldecode转码回unicode到手机再解析为emoji表情。

    获取字符串长度mb_strlen,按字符来截取字符串mb_substrmb_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."
    ";// 周梦康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."
    ";

    20150204001219_21486

    php 就这么轻松愉快的解决了。

    Java 版本

    考虑到想使用php里面的套路,对原字符串逐个字符获取其长度,如果超过3个字节,那么则编码下,就能存储了,依照上次的经验,我写了如下代码

    String a = "uD83DuDE01";// 一个 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();
        }
    }

    20150610235033_89389

  • 相关阅读:
    IE浏览器下ajax缓存导致数据不更新的解决方法
    .NET C# Tostring format 格式化字符串
    解决jquery.validate.js的验证bug
    jquery中attr和prop的区别
    Jquery操作下拉框(DropDownList)实现取值赋值
    【MVC】自定义Scaffold Template
    【HTML5+MVC4】xhEditor网页编辑器图片上传
    回归与梯度下降法及实现原理
    浅谈强化学习的方法及学习路线
    【OpenCV学习笔记之一】图像加载,修改及保存
  • 原文地址:https://www.cnblogs.com/exmyth/p/8378838.html
Copyright © 2011-2022 走看看