使用Java代码过滤掉乱码字符

使用Java代码过滤掉乱码字符转自:http://www.cnblogs.com/en-heng/p/5320024.html最近在日志数据清洗时遇到中文乱码,如果只要有非中文字符就将该字符串过滤掉,这种方法虽简单但并不可取,因为比如像Xperia™主題、天天四川麻将Ⅱ这样的字符串也会被过滤掉。1.Unicode编码Unicode编码是一种涵盖了世界上所有语言、标点等字符的编码方式,简单一点说

大家好,又见面了,我是你们的朋友全栈君。

转自:http://www.cnblogs.com/en-heng/p/5320024.html

最近在日志数据清洗时遇到中文乱码,如果只要有非中文字符就将该字符串过滤掉,这种方法虽简单但并不可取,因为比如像Xperia™主題天天四川麻将Ⅱ这样的字符串也会被过滤掉。

1. Unicode编码

Unicode编码是一种涵盖了世界上所有语言、标点等字符的编码方式,简单一点说,就是一种通用的世界码;其编码范围:U+0000 .. U+10FFFF。按Unicode硬编码的区间进行划分,Unicode编码被分成若干个block ( Unicode block);每一个Unicode编码专属于唯一的Unicode block,Unicode block之间互不重叠。从码字的本身的属性出发,Unicode编码被分成了若干script ( Unicode script);比如,与中文相关的字符、标点的scriptHan包括block如下:

  • CJK Radicals Supplement
  • Kangxi Radicals
  • CJK Symbols and Punctuation中的15个字符
  • CJK Unified Ideographs Extension A
  • CJK Unified Ideographs
  • CJK Compatibility Ideographs
  • CJK Unified Ideographs Extension B
  • CJK Unified Ideographs Extension C
  • CJK Unified Ideographs Extension D
  • CJK Unified Ideographs Extension E
  • CJK Compatibility Ideographs Supplement

其中,常见的中文字符在CJK Unified Ideographs block;此外,考虑繁体字及不常见字等,CJK还有A、B、C、D、E五个extension。Basic Latin block完整地包含了ASCII码的控制字符、标点字符与英文字母字符。

Unicode编码与block、script之间的映射关系,具体可参看这里

2. Java的字符编码

JDK完整实现Unicode的block与script:

Char c = '☎' Character.UnicodeBlock ub = Character.UnicodeBlock.of(c) Character.UnicodeScript uc = Character.UnicodeScript.of(c);

Java中的字符char内置的编码方式是UTF-16,当char强转成int类型时,其返回值是unicode编码值,只有当getbyte时才返回的是utf-8编码的byte:

String s = "\u00a0"; String.format("\\u%04x", (int) s.charAt(0)) // --> \u00a0 import org.apache.commons.codec.binary.Hex; Hex.encodeHex(s.getBytes()) // --> c2a0

UTF-8是Unicode字符的变长前缀编码的一种实现,二者之间的对应关系在这里.现在我们回到开篇过滤中文乱码的问题,有一个基本解决思路:

  • 去掉各种标点字符、控制字符,
  • 计算剩下字符中非中文字符所占的比例,如果超过阈值,则认为该字符串为乱码串

完整代码如下:

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 || ub == Character.UnicodeBlock.VERTICAL_FORMS // ascii || ub == Character.UnicodeBlock.BASIC_LATIN ) { return true; } else { return false; } } 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; } }

为了得到更为完整的可接受的字符表,定义isUserDefined方法(具体字符表与日志中的字符有关系);加上了Number FormsEnclosed AlphanumericsLetterlike Symbols这三个block,以及\u00a0(Non-breaking space)字符与\ufeff(ZERO WIDTH NO-BREAK SPACE)字符。

3. 参考资料

[1] Wikipedia, Unicode block.
[2] Tong Zeng, Java 中文字符判断 中文标点符号判断.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/131923.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 对口计算机一分一档2019河北,最新!2019河北高考一分一档统计表公布![通俗易懂]

    对口计算机一分一档2019河北,最新!2019河北高考一分一档统计表公布![通俗易懂]免费申请学习规划请选择学习阶段学前小学初中高中大学留学其他已为25937位学员提供学习规划*验证码*短信验证码{“text1”:{“label”:”薄弱科目”,”placeholder”:”请输入你的薄弱科目”,”required”:1,”formType”:”text”,”group”:”dynamic”,”name”:”text1″,”type”:”text”,”data”:[]},”cour…

  • 2018一切刚刚开始

    简单计划,努力工作,坚持输出,积极生活,让生活更加美好。开始新的一年的第一周工作,生活从新年中慢慢回归,慢慢进入节奏。每一年都会写一些新的开始的计划,然后到年终的时候很多计划都没有实现,但是不能因为很多没有实现就不去写新一年的一些想法,万一今年实现了呢?努力工作在一家公司,从一个新员工慢慢开始变成老员工了,思维方面要调整,还要有新员工的那份热情,也要老员工相应的承担了,要承…

  • 不同数据库oracle mysql SQL Server DB2 infomix sybase分页查询语句

    不同数据库oracle mysql SQL Server DB2 infomix sybase分页查询语句

  • 【经典算法大全】收集51种经典算法 初学者必备

    【经典算法大全】收集51种经典算法 初学者必备《经典算法大全》是一款IOS平台的应用。里面收录了51种常用算法,都是一些基础问题。博主觊觎了好久,可悲哀的是博主没有苹果,所以从网上下了老奔的整理版并且每个都手敲了一遍。虽然网上也有博客贴了出来,但是自己写写感觉总是好的。现在分享个大家。代码和运行结果难免有出错的地方,请大家多多包涵。 1.河内之塔(汉诺塔)2.费式数列3.巴斯卡三角形4.三色棋5.老鼠走迷宫(1

  • 简述django请求生命周期_django请求的生命周期

    简述django请求生命周期_django请求的生命周期Django请求生命周期分析1.客户端发送请求在浏览器输入url地址,例如www.baidu.com,浏览器会自动补全协议(http),变为http://www.baidu.com,现在部分网站都

  • np管理器去更新(npx命令)

    一、npm查看某个模块的版本信息,例如element框架npminfoelement-ui二、npm更新模块到最新版本npminstallelement-ui@latestnpm更新模块到某个版本npminstallelement-ui@2.12.0更多:vs2019中怎么把tab补全换成空格补全;vs2019如何关闭空格自动补…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号