一、java开发之乱码处理

JAVA实现自定义乱码判断逻辑


前言

在大数据日志收集中,出现各式各样的数据都不奇怪,因为前端采集的系统不能考虑到所有的突发情况。所以遇到乱码也是很常见的。那么出现乱码我们一般采取两种方式,要么保留,先存储到磁盘上,但是这种处理方式后续可能在分析落地数据库的时候会影响显示或者插入报错。第二种是直接过滤掉,放置后续的各种问题排查。不过我们还有第三种选择的,那就是自定义过滤乱码的数据。

⚠️⚠️⚠️引用文献

作者地址来源
东边的小山https://blog.csdn.net/yelin042/article/details/82151636CSDN
易霂https://www.jianshu.com/p/5590b8ef0dec简书

一、乱码是什么?

在这里插入图片描述

我们一般定义乱码就是非中文,非字母,非标点符合等之外的特殊字符。这是从一般理解上来定义的,那么从官方定义来讲。我这里说通俗点。也也就是在传输的过程中,字符的编码方式和解码方式不一致,就会造成乱码。举个🌰,MySQL的utf-8和utfmb4,前者使用一个字符三字节,后者使用一个字符4字节,这样的话,从前者数据库导数据到后者那么就会出现乱码。这就相当于你在我们国家学的法律制度,去了外国你要是还按照这个法律来就乱套了,人家不认。

二、自定义:视什么为乱码

⚡️⚡️⚡️⚡️代码注释很详细了,这里不多加解释了

package com.langjian;

import java.util.Base64;

public class ChineseUtill {


    //是否是纯汉字
    private static boolean isChinese(char c) {
        Character.UnicodeScript sc = Character.UnicodeScript.of(c);
        if (sc == Character.UnicodeScript.HAN) {
            return true;
        }
        return false;
    }
    //是否是标点符合
    public static boolean isPunctuation(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (    // punctuation, spacing, and formatting characters  标点、间距和格式字符
                ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                        // symbols and punctuation in the unified Chinese, Japanese and Korean script  中日韩统一体中的符号与标点符号
                        || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                        // fullwidth character or a halfwidth character  全角字符还是半角字符
                        || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                        // vertical glyph variants for east Asian compatibility  与东亚兼容的垂直字形变体
                        || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS
                        // vertical punctuation for compatibility characters with the Chinese Standard GB 18030 GB18030与汉字兼容的垂直标点符号
                        || ub == Character.UnicodeBlock.VERTICAL_FORMS
                        // ascii
                        || ub == Character.UnicodeBlock.BASIC_LATIN
        ) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 为了得到更为完整的可接受的字符表,定义isUserDefined方法(具体字符表与日志中的字符有关系);加上了Number Forms、Enclosed Alphanumerics、Letterlike Symbols这三个block,以及\u00a0(Non-breaking space)字符与\ufeff(ZERO WIDTH NO-BREAK SPACE)字符
     *
     * 简单来讲,就是我们在这可以提前录入一些我们提前已经知道不是乱码的符号
     * 比如:Ⅱ 或者 ™
     * @param c
     * @return
     */
    private static Boolean isUserDefined(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.NUMBER_FORMS //数字表
                || ub == Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS //随附字母数字
                || ub == Character.UnicodeBlock.LETTERLIKE_SYMBOLS //目录符号
                || c == '\ufeff'
                || c == '\u00a0'
        )
            return true;
        return false;
    }
    //判断当前字符串是否是混乱的(乱码太多)。
    public static Boolean isMessy(String str)  {
        float chlength = 0;
        float count = 0;
        for(int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if(isPunctuation(c)
//                    || isUserDefined(c)
            )
                continue;
            else {
                if(!isChinese(c)) {
                    count = count + 1;
                }
                chlength ++;
            }
        }
        float result = count / chlength;
        if(result > 0.3)
            return true;
        return false;
    }

    public static void main(String[] args){

        System.out.println(isMessy("天天四川麻将ⅡⅡⅡⅡⅡ™™™™™™™™™™™™™"));
        //返回true
    }

}

总结

以上就是关于自定义乱码的过滤逻辑,在我工作环境中,因为数据存储在集群上,使用读时模式不会太在意数据的格式类型包括是否乱码,展示的时候也不影响,有时候会过滤掉这部分乱码数据。不过如果是写入规范的数据库比如mysql,一般会采取处理和写入两方都保证一直的字符集来避免报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值