Java实现过滤中文乱码
最近在日志数据清洗时遇到中文乱码,如果只要有非中文字符就将该字符串过滤掉,这种方法虽简单但并不可取,因为比如像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 Forms、Enclosed Alphanumerics、Letterlike Symbols这三个block,以及\u00a0(Non-breaking space)字符与\ufeff(ZERO WIDTH NO-BREAK SPACE)字符。
3. 参考资料
[1] Wikipedia, Unicode block.
[2] Tong Zeng, Java 中文字符判断 中文标点符号判断.
Java实现过滤中文乱码的更多相关文章
- java socket输入输出中文乱码问题
http://hi.baidu.com/linjk03/item/e2028bfd990c14ea1a111feb 统一了输入输出的编码格式,是不会有乱码问题出现的. 构造Reader或Write ...
- java: jsp:param中文乱码
java: jsp:param中文乱码 假如a.jsp/b.jsp文件中 a.jsp代码: 需要加入:request.setCharacterEncoding("UTF-8") ...
- Java编程中中文乱码问题的研究及解决方案
0 引言 Java最大的特性是与平台的无关性及开发环境的多样性.字符串被Java应用程序转化之前,是根据操作系统默认的编码方式编码.Java语言内部采用Unicode编码,它是定长双字节编码,即任何符 ...
- java开发中中文乱码总结
1.jsp页面内容显示乱码 这种乱码原因很简单,一般的工具或解码程序对中文字符解析时采用默认的解码方式: <%@ page contentType="text/html; charse ...
- java链接mysql 中文乱码
{转!} 背景: 由于最近在开发一个APP的后台程序,需要Java连接远程的MySQL数据库进行数据的更新和查询操作,并且插入的数据里有中文,在插入到数据库后发现中文都是乱码.网上查了很多教程,最后都 ...
- 201671010127 2016—2017—2 Java怎样解决Java程序中中文乱码的问题。
这是本次第二次分享新手在编程中遇到的问题,相信很多Java新手和我一样,在Java编程中会遇到中文乱码的情况,下面我就给大家分享我遇到问题和解决问题的具体过程. 我先用Notepad++写了一个如下的 ...
- 解决Ubuntu下的Eclipse打开Windows编写的java代码的中文乱码
其实所有的中文乱码 问题都是编码不同所导致的.这里要想让eclipse能正常显示出汉字,就要修改它的字符编码 步骤如下: 1 ,点击菜单栏中的Window(窗口),选择Preferences(首选项) ...
- java 页面传输中文乱码解决方式
post 中文乱码解决方案 接受数据的时候设置 request.setCharacterEncoding("utf-8");//编码必须和页面编码一致 页面设置 <%@pag ...
- JAVA下载文件中文乱码问题
http://blog.itpub.net/92037/viewspace-788900/ 最后的中文乱码没有解决 现在我在系统中用到了两个组件,smartupload,一个支持中文,一个不支持.但是 ...
随机推荐
- oracle在impdp时报ORA-31655和ORA-39154
检查表空间大小设置的是否合理. 另外可以试试 grant IMP_FULL_DATABASE to user;增加导入权限. (转)
- vs的dll引用机制
vs2012编译的时候,遇到一个问题就是项目A中运行时缺失dll的问题,项目A引用类库B,类库B引用了x,y等dll,编译A项目的时候,出现x没拷贝到bin 目录. 通过跟踪编译输出发现,x没拷贝的原 ...
- mono的远程调试
mono可以让.net程序运行在linux平台上.于是.net程序员有了mono之后就转身跨平台了.但开放环境往往还是在windows下,于是有了这样的需求,是否可以用windows下的源码来实机调试 ...
- UML动态模型图简单介绍
UML动态模型图描述了系统动态行为的各个方面,包括用例图.序列图.协作图.活动图和状态图.下面就每种图做一个简单介绍: 用例图 用例图描述系统外部的执行者与系统提供的用例之间的某种联系.所谓用例是指对 ...
- jQuery+ASP.NET MVC基于CORS实现带cookie的跨域ajax请求
这是今天遇到的一个实际问题,在这篇随笔中记录一下解决方法. ASP.NET Web API提供了CORS支持,但ASP.NET MVC默认不支持,需要自己动手实现.可以写一个用于实现CORS的Acti ...
- Web Essentials之Bundling
返回Web Essentials功能目录 本篇目录 介绍 样例文件 已知行为 介绍 这篇要讲的是Bundling,我看很多人把它翻译为捆绑,如果你喜欢你也可以这么理解,我是不太习惯,我还是喜欢它为bu ...
- RCP: JDT 根据org.eclipse.jdt.core.IJavaElement对象获取org.eclipse.jdt.core.dom.ASTNode对象
JDT中有两套Java文件模型映射. 其核心类\接口分别为: org.eclipse.jdt.core.IJavaElement和org.eclipse.jdt.core.dom.ASTNode IJ ...
- Alpha阶段冲刺总结
Alpha阶段冲刺阶段总结 预期计划: 本阶段的预期计划是实现打地鼠游戏的基本功能,包括:游戏功能.难度调节功能.计时功能.计数记分功能.DIY设置功能.分数记录功能. 实际进展: 在经过三周的Alp ...
- IE浏览器不能自动显示PDF文件的解决办法
今天更新了Adobe的PDF Reader,更新后发现在网页上无法预览PDF文件了,点击PDF的连接,浏览器就会提示下载或者打开,感觉很不爽,经过一番百度,找到了解决办法,在这里分享一下. 打开IE浏 ...
- [ZigBee] 15、Zigbee协议栈应用(一)——Zigbee协议栈介绍及简单例子(长文,OSAL及Zigbee入门知识)
1.Zigbee协议栈简介 协议是一系列的通信标准,通信双方需要按照这一标准进行正常的数据发射和接收.协议栈是协议的具体实现形式,通俗讲协议栈就是协议和用户之间的一个接口,开发人员通过使用协议栈来使用 ...