使用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)


相关推荐

  • MySQL comment_mysql和oracle的区别

    MySQL comment_mysql和oracle的区别iconv用法场景说明将UTF-8的编码转换成GBK编码,使用Notepad++创建一个UTF-8(无BOM)的编码文件,文件内容简单为风雨在途,保存文件名称为utf8.txt,转换之后存储文件名称为gbk.txt.1.1:iconv命令的使用iconv-fUTF8-tGBKgbk.txt1.2:iconv函数的使用#includesize_ticonv(iconv_tcd…

    2022年10月22日
  • java databus_linkedin 的 databus 部署「建议收藏」

    java databus_linkedin 的 databus 部署「建议收藏」1.下载源码复制ojdbc.jar到相应的文件夹gitclonehttps://github.com/linkedin/databus/sandbox-repo/com/oracle/ojdbc6/11.2.0.2.0/ojdbc6-11.2.0.2.0.jar2.在subprojects.gradle中加上options.addStringOption(‘encodi…

    2022年10月17日
  • listagg oracle10_oracle伪列

    listagg oracle10_oracle伪列oracle函数listagg的使用说明

  • 使用Golang实现PHP的Addslashes和Stripslashes「建议收藏」

    使用Golang实现PHP的Addslashes和Stripslashes「建议收藏」//addslashes()函数返回在预定义字符之前添加反斜杠的字符串。//预定义字符是://单引号(’)//双引号(”)//反斜杠(\)funcAddslashes(strstring)string{ tmpRune:=[]rune{} s…

  • 俄罗斯方块(C语言实现)

    俄罗斯方块(C语言实现)文章目录游戏说明游戏效果展示游戏代码游戏代码详解游戏框架构建隐藏光标光标跳转初始化界面初始化方块信息颜色设置画出方块空格覆盖合法性判断游戏主体逻辑函数判断得分与结束主函数游戏说明俄罗斯方块相信大家都知道,这里就不再介绍什么游戏背景了,我这里对本代码实现的俄罗斯方块作一些说明:按方向键的左右键可实现方块的左右移动。按方向键的下键可实现方块的加速下落。按空格键可实现方块的顺时针旋转。按Esc键可退出游戏。按S键可暂停游戏,暂停游戏后按任意键继续游戏。按R键可重新开始游戏。除此之外,本游戏还

  • 解决Android SDK 下载太慢[通俗易懂]

    解决Android SDK 下载太慢[通俗易懂]1、打开androidsdkmanager2、打开tool->options,如图所示3、将ProxySettings里的HTTPProxyServer和HTTPProxyPort分别设置成mirrors.neusoft.edu.cn和80将Others中的Forcehttps://…sourcestobefetchedusinghttp://.

发表回复

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

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