2013-07-25 49 views
2

我想分解一些文本。例如,從這裏:http://docs.oracle.com/javase/6/docs/api/java/text/Normalizer.html簡單的標準化文本示例不起作用

U+00C1 LATIN CAPITAL LETTER A WITH ACUTE (Á) 

或作爲兩個獨立的字符( 「分解」 的形式):

U+0041 LATIN CAPITAL LETTER A 
    U+0301 COMBINING ACUTE ACCENT 

我下面從Oracle本教程頁:http://docs.oracle.com/javase/tutorial/i18n/text/normalizerapi.html

這個簡單的情況下確實不適合我:

  • 原詞:"schön"
  • NFC:"schön"
  • NFD:"scho\u0308n"
  • NFKC:"schön"
  • NFKD:"scho\u0308n"

在上述所有情況下,功能Normalizer.normalize("schön", form)(其中形式爲Normalizer.Form.NFC一個,Normalizer.Form.NFD等),結果是一樣的:"schön"

此代碼不起作用o n在Linux上使用Eclipse JDT的Oracle JDK 1.6或1.7安裝。

String n = Normalizer.normalize("schön", Normalizer.Form.NFD); 

結果n總是「schön」。

這個「問題」聞起來像(1)我完全誤解了這個函數,或者(2)一個糟糕的環境。我被卡住了。有什麼建議麼?我的系統設置非常好。

+1

「反正規化是錯誤的術語。這意味着結果將不會以正常形式出現。 「分解」或「正常化爲NFD」是正確的。 –

+2

你如何測試結果?打印不算。 NFD中的字符串與NFC中的相同字符串正典等效。正則等價的字符串需要被實現視爲相同的字符串,並將它們打印出來不會顯示差異。你需要單獨看字符。下面是一個通過顯示字符串具有不同長度來顯示差異的示例:https://ideone.com/RzSp6Y –

+0

@R。MartinhoFernandes:你對denorm vs decomp有所瞭解。我更新了我的文字。 – kevinarpe

回答

3

信用歸因於@ R.MartinhoFernandes。我不知道結果將與輸入相同。今天我學到了關於Unicode de/composition的新內容。

簡而言之:

String.valueOf('Á').equals(String.valueOf('\u00C1')) 
String.valueOf('A').equals(String.valueOf('\u0041')) 

和:

Normalizer.normalize("Á", Normalizer.Form.NFD).equals("\u0041\u0301") 
!String.valueOf('Á').equals("\u0041\u0301") 

但是:

System.out.println("Á\u0041\u0301") 

會打印:

ÁÁ 
+0

我還在http://info.michael-simons.eu/2013/01/25/hidden-java-gems-java-text-normalizer/中發現了更多有用的示例。 – reallynice

0

只是做到這一點,它會做的工作:

String n = Normalizer.normalize("schön", Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); 
+0

什麼是「這個」?什麼是「工作」 – UmNyobe

+0

@UmNyobe它將用「非特殊」等效替換所有Unicode特殊字符,因此「ö」將變爲「o」。 – mradzinski