如何将“// u ****”之类的字符串转换为文本?

时间:2016-12-07 13:08:47

标签: haskell unicode

我想在Haskell中将类似“// u ****”的字符串转换为text(unicode)。

我有一个Java属性文件,它包含以下内容:

WHERE

我想在Haskell中将其转换为文本(Unicode)。

我想我可以这样做:

  1. 将“\ u ****”转换为word8数组
  2. 将word8数组转换为ByteString
  3. 使用i18n.test.key=\u0050\u0069\u006e\u0067\u0020\uc190\uc2e4\ub960\u0020\ud50c\ub7ec\uadf8\uc778 将ByteString转换为文本
  4. 但是第1步对我来说并不复杂。

    如何在Haskell中完成?

3 个答案:

答案 0 :(得分:1)

如果用\u替换\x,那么这是一个有效的Haskell字符串文字。

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

如果需要,您可以转换为Text,或将其保留为String或其他任何内容。

答案 1 :(得分: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]

备注:

  • 您的字符串是UTF16编码的,因此您需要decodeUtf16BE
  • 如果字符串中还有其他字符,则解码将失败。仅当您删除尾随i
  • 时,此代码才适用于您的示例
  • 通过附加0x来构建单词,特别是使用read来构建单词非常慢,但会为小数据提供技巧。

答案 2 :(得分:0)

注意,Java通常使用UTF-16对其字符串进行编码,因此将字节解释为UTF-8可能不起作用。

如果文件中的代码是UTF-16,则需要执行以下操作:

  1. 找到每个quadrupel的数值(Unicode代码点)
  2. 检查这是否是一个高代理字符。如果是这样,则以下字符将是低代理字符。这对代理字符可以映射到Unicode点。
  3. 使用map fromEnum
  4. 从您的unicode数字列表中创建一个字符串

    以下是来自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库。