使用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 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 中文字符判断 中文标点符号判断.

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

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 经典sql server基础语句大全

    经典sql server基础语句大全一、基础1、说明:创建数据库CREATEDATABASEdatabase-name2、说明:删除数据库dropdatabasedbname3、说明:备份sqlserver—创建备份数据的deviceUSEmasterEXECsp_addumpdevice’disk’,’testBack’,’c:\mssql7backup\MyNwind_1.dat’…

    2022年4月29日
  • JDK卸载和彻底删除

    JDK卸载和彻底删除第一步:点击“控制面板”。第二步:点击“卸载程序”。第三步:进入到“程序和功能”界面,找到jdk的两个程序:①java8update171(64-bit);②javaSEDevelopmentKit8update171(64-bit);右击卸载即可第四步:在“运行”中输入Regedit,打开注册表编辑器,找到HKEY_LOCAL_MACHINE/SOFTWARE/JavaSo…

    2022年6月30日
  • c语言中switch是什么语句_switch结构c语言

    c语言中switch是什么语句_switch结构c语言c语言中switch的用法是:功能:switch语句是多分支选择语句.用来实现多分支选择结构.if语句只有两个分支可供选择,而实际问题中常常要用到多分支的选择.例如,学生成绩分类(90为”…

    2022年8月30日
  • Generic Host Process for Win32 Services 错误

    Generic Host Process for Win32 Services 错误机器运行时防火墙一直提示“GenericHostProcessforWin32Services”访问网络,选阻止后系统就一直弹出一个GenericHostProcessforWin32Services遇到问题需要关闭的对话框!在资源管理器中把系统文件的隐藏属性打开后,发现每个盘的根目录下和C:/WINDOWS目录下都有一个gg.exe文件,每个盘的根目录下有一个autoru

    2022年10月12日
  • js中settimeout()的用法详解_js中setattribute

    js中settimeout()的用法详解_js中setattributesetTimeout与setTimeInterval均为window的函数,使用中顶层window一般都会省去,这两个函数经常稍不留神就使用错了。setTimeout内的函数先不执行,隔一段时间后再执行,函数后面的数字是隔的时间,单位是毫秒(千分之一秒)比如:setTimeout(‘alert(“helloworld!”)’,400);setInterval()方法可按照

    2022年10月5日
  • 用python画爱心代码_python打印心形图案

    用python画爱心代码_python打印心形图案1、工具python3.0及以上版本;pycharm或其他开发环境2、思路首先,把你想说的话想好,我们用split()函数按空格切割成一个一个词其次,了解心形函数,百度一下哈,这个很多的,比如下面这个:再次,打印第一个词,两个for循环。一行一行打印,在函数内部的我们打印词,在函数外面的打印空格即可…

    2022年9月4日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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