2016-12-07 56 views
1

我想將「// u ****」這樣的字符串轉換爲Haskell中的文本(unicode)。如何將字符串「// u ****」轉換爲文本?

我有一個Java propertyes文件,它具有以下內容:

i18n.test.key=\u0050\u0069\u006e\u0067\u0020\uc190\uc2e4\ub960\u0020\ud50c\ub7ec\uadf8\uc778 

我想將它轉換爲文本(Unicode)的哈斯克爾。

我想我能做到這一點是這樣的:

  1. 轉換 「\ü****」,以word8陣列
  2. 轉換word8數組的字節字符串
  3. 使用Text.Encoding.decodeUtf8轉換字節字符串文本

但是第1步對我來說並不複雜。

如何在Haskell中做到這一點?

回答

1

一個簡單的解決方案可能是這樣的:

decodeJava = T.decodeUtf16BE . BS.concat . gobble 

gobble []      = [] 
gobble ('\\':'u':a:b:c:d:rest) = let sym = convert16 [a,b] [c,d] 
           in sym : gobble rest 
gobble _      = error "decoding error" 

convert16 hi lo = BS.pack [read $ "0x"++hi, read $ "0x"++lo] 

注:

  • 你的字符串是UTF-16編碼,因此你需要decodeUtf16BE
  • 如果字符串中有其他字符,解碼將失敗。只有當您刪除尾部i時,此代碼才能與您的示例一起使用。
  • 通過追加0x構建單詞,特別是使用read的速度非常緩慢,但是對於小數據來說會起到訣竅的作用。
+0

謝謝。它運作良好〜 –

1

如果用\u替換爲\x,那麼這是一個有效的Haskell字符串文字。

my_string = "\x0050\x0069\x006e..." 

然後可以轉換爲Text,如果你想,或者將其作爲String,或什麼的。

+0

這是不完全正確的。有2個Java字符表示的unicode字符。看到我的答案。 – Ingo

0

注意,Java通常使用UTF-16對其字符串進行編碼,因此將字節解釋爲UTF-8可能無效。

如果你的文件的代碼是UTF-16,你需要做到以下幾點:

  1. 每個quadrupel
  2. 檢查發現的數值(Unicode代碼點),如果這是一個高代理字符。如果是這樣,下面的字符將是低代理字符。這對代理字符可以映射到一個Unicode點。
  3. 從您的Unicode數字列表的字符串與map fromEnum

以下是從Java文檔http://docs.oracle.com/javase/7/docs/api/報價:

CHAR數據類型(因此,該值是一個Character對象封裝)基於原始Unicode規範,該規範將字符定義爲固定寬度的16位實體。此後,Unicode標準已被更改爲允許表示要求多於16位的字符。合法代碼點的範圍現在是U + 0000到U + 10FFFF,稱爲Unicode標量值。 (請參閱Unicode標準中U + n表示法的定義。)

從U + 0000到U + FFFF的一組字符有時稱爲基本多語言平面(BMP)。代碼點大於U + FFFF的字符稱爲補充字符。 Java平臺在char數組和String和StringBuffer類中使用UTF-16表示形式。在這種表示中,補充字符表示爲一對char值,第一個來自高代理範圍(\ uD800- \ uDBFF),另一個來自低代理範圍(\ uDC00- \ uDFFF)。

Java有方法將高代理字符和低代理字符組合起來以獲得Unicode點。您可能需要檢查java.lang.Character類的來源以瞭解它們究竟是如何做到這一點的,但我想這是一些簡單的位操作。

另一種可能性是檢查執行UTF-16解碼的Haskell庫。

+0

thx非常。你說得對,這是Utf-16解碼。 –

相關問題