1. 程式人生 > >Java實現過濾中文亂碼

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 FormsEnclosed AlphanumericsLetterlike Symbols這三個block,以及\u00a0(Non-breaking space)字元與\ufeff(ZERO WIDTH NO-BREAK SPACE)字元。

3. 參考資料

相關推薦

Java實現過濾中文亂碼

最近在日誌資料清洗時遇到中文亂碼,如果只要有非中文字元就將該字串過濾掉,這種方法雖簡單但並不可取,因為比如像Xperia™主題、天天四川麻將Ⅱ這樣的字串也會被過濾掉。 1. Unicode編碼 Unicode編碼是一種涵蓋了世界上所有語言、標點等字元的編碼方式,簡單一點說,就是一種通用的世界碼;其編碼範圍:U

Java中的中文亂碼問題

jsp req 安裝路徑 漢字 mysql配置文件 rac name line 進行 客戶端向服務器發送請求時,有兩種方式post和get請求,當客戶端提交的內容有中文時。服務器要進行設置才能獲得中文,否則獲得的是亂碼。那麽怎麽設置呢:在servlet中進行設置,有兩種情

Android Studio解決Java程序輸出中文亂碼

roc 中文 Coding str uil nbsp process option clas 經查閱資料,發現需要手動在build.gradle中添加代碼 //新版 tasks.withType(JavaCompile) { options.encoding = "UT

Android第二十三課 Java檔案讀取中文亂碼

1 位元組流以及編碼轉換說明 String str = "中"; byte[] b_gbk =str.getBytes("GBK"); byte[] b_utf8 =str.getBytes("UTF-8"); String s_gbk = newString(b_gbk,"GBK"); Str

JAVA實現過濾掉文字中的表情

公司是做電商的,在資料採集這方面,要進行大量的資料採集,在資料採集的時候遇到了很多的問題,有一些文字包含表情,資料庫用的是utf8字符集,這樣就儲存到資料庫中就會報錯,本來是可以把資料庫的字符集改成utf8mb4,這樣就可以儲存帶有表情,,但是考慮一直在使用utf8,則就使用

Linux中java log輸出中文亂碼

比如這樣一段程式碼: logger.debug("中文亂碼?Chinese");輸出結果是這樣的: 2016-06-12 10:24:46,130:DEBUG main (CleanupTaskTest.java:27) - ?????Chinese 執行lo

Java實現中文名稱排序

//定義排序函式 public static String[] getSortOfChinese(String[] a) { // Collator 類是用來執行區分語言環境這裡使用CHINA Comparator cmp = Collator.getInstance(java.util

java 頁面傳輸中文亂碼解決方案

post 中文亂碼解決方式 接受資料的時候設定 request.setCharacterEncoding("utf-8");//編碼必須和頁面編碼一致 頁面設定 <%@page import="java.net.URLDecoder"%> <%@page

表單提交時js&java暴力解決中文亂碼

頁面: var data = encodeURIComponent(data); 伺服器: String data = URLDecoder.decode(URLDecoder.decode(

java實現中文財務讀取金額方式

這是我的第一篇文章。 使用java實現的,中文財務讀取金額方式。如:12345讀作“壹萬貳仟叄拾肆元整”。 一般拿到一個數字,首先看是否存在小數,然後按照整數部分和小數部分分別讀取,然後組合成最終的結果。 實現過程已經參考了財務讀取金額的教程,如有錯誤,歡迎指正。 下面

java中的中文亂碼處理

1.在頁面設定編碼方式(UTF-8)2.編寫字元編碼過濾器 在過濾器中寫下一下程式碼:HttpServletRequest request = (HttpServletRequest)arg0;HttpServletResponse response = (HttpServ

java servlet 接收中文亂碼

private FilterConfig filterConfig; public void init(FilterConfig filterConfig) throws ServletExc

Java Web專案中文亂碼以及解決辦法

一、中文亂碼說明  在Java Web專案中,由於pageEncoding、contentType和charset等編碼屬性的設定不恰當往往導致顯示中文字元會出現亂碼問題。例如,在Java Web專案

Java讀取檔案----中文亂碼問題

  在用Java讀寫檔案時,發現讀取的檔案在用控制檯輸出之後中文部分出現了亂碼的問題。   先不吐槽為毛中文這麼多怪事。   對於不同的檔案,它們的預設編碼格式可能是不同的,有的是gbk,有的是utf-8,又或者是ISO-8859-1之類的。   總而言之,一遇到中文就會出

java過濾器解決中文亂碼_百度文庫

java中文亂碼過濾器2010-10-14 10:56:07| 分類: java | 標籤: |字號大 中 小 訂閱 package filters; import java.io.IOException; import javax.servlet.Filter; i

java解決sqlserver中文亂碼

/** * 為了解決中文亂碼問題,一律轉城Unicode * @param str * @return */ public String chinaToUnicode(String str) { String result = ""; for (i

java 寫 xml 中文亂碼

今天用java寫xml檔案,發現寫完後xml檔案的中文就變成了亂碼, 解決辦法:把xml檔案的頭部編碼改為utf-8,StreamResult編碼方式也改為utf-8. =============部分程式碼============= public String crea

java-Socket接受中文亂碼的解決

伺服器傳送一條資料如: BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); PrintWriter out = new PrintWriter(cli

載入到Myeclipse中的java檔案出現中文亂碼的問題

        用MyEclipse開啟Web工程的程式碼後,發現個別java檔案出現中文顯示亂碼的問題,到網上查了一下,此亂碼問題可以通過下面的兩種辦法來解決:         1、將整個proje

java web 解決中文亂碼問題(全面總結)

  在開發一個完整的web專案時,總是會遇到各種各樣的中文亂碼問題,例如頁面顯示亂碼,表單提交亂碼,資料庫儲存亂碼等          等,雖然目前也能找到各種各樣的解決方案,但是大部分都沒有總結全面。(我也遇到了中文亂碼問題 這是我抄襲來的 如果原作者需要 請通知我刪