在数学中读取UTF-8编码的文本文件 [英] Reading an UTF-8 encoded text file in Mathematica

查看:19
本文介绍了在数学中读取UTF-8编码的文本文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在数学中读取utf-8编码的文本文件?

这就是我现在所做的:

text = Import["charData.txt", "Text", CharacterEncoding -> "UTF8"];

但它告诉我

$CharacterEncoding::utf8: "The byte sequence {240} could not be interpreted as a character in the UTF-8 character encoding"

等等。我不知道为什么。我相信该文件是有效的UTF-8。

这是我尝试读取的文件:

http://dl.dropbox.com/u/38623/charData.txt

数学

简写版本:推荐答案的UTf-8功能不适用于超过16位的字符代码。如果可能,请改用UTF-16编码。但请注意,MATHEMICA对17位以上字符代码的处理通常是有缺陷的。长文本紧随其后...

正如许多评论者所指出的那样,问题似乎出在数学软件对编码大于16位的Unicode字符的支持上。引用的文本文件中的第一个这样的字符是U+20B9B(𠮛),它出现在第10行。

部分数学前端版本(如64位Windows 7上的8.0.1)在直接输入时可以处理有问题的字符:

In[1]:= $c="𠮛";

但是如果我们试图从它的Unicode创建字符,我们就会遇到麻烦:

In[2]:= 134043 // FromCharacterCode

During evaluation of In[2]:= FromCharacterCode::notunicode:
A character code, which should be a non-negative integer less
than 65536, is expected at position 1 in {134043}. >>
Out[2]= FromCharacterCode[134043]

然后人们想知道,数学认为这个角色的代码是什么?

In[3]:= $c // ToCharacterCode
        BaseForm[%, 16]
        BaseForm[%, 2]

Out[3]= {55362,57243}
Out[4]//BaseForm= {d842, df9b}
Out[5]//BaseForm= {1101100001000010, 1101111110011011}

我们得到的不是预期的单个Unicode值,而是恰好与该字符的UTF-16表示相匹配的两个代码。MATHEMICAL A也可以执行逆变换:

In[6]:= {55362,57243} // FromCharacterCode

Out[6]= 𠮛

那么,数学学院对这个字符的UTF-8编码的概念是什么?

In[7]:= ExportString[$c, "Text", CharacterEncoding -> "UTF8"] // ToCharacterCode
        BaseForm[%, 16]
        BaseForm[%, 2]

Out[7]= {237,161,130,237,190,155}
Out[8]//BaseForm= {ed, a1, 82, ed, be, 9b}
Out[9]//BaseForm= {11101101, 10100001, 10000010, 11101101, 10111110, 10011011}
细心的读者会发现这是字符的UTF-16编码的UTF-8 encoding。MATHIGHICA是否可以解码此有趣的编码?

In[10]:= ImportString[
           ExportString[{237,161,130,237,190,155}, "Byte"]
         , "Text"
         , CharacterEncoding -> "UTF8"
         ]

Out[10]= 𠮛

是的,它可以!但是..。那又怎样?

此字符的实际UTF-8表达式如何:

In[11]:= ImportString[
           ExportString[{240, 160, 174, 155}, "Byte"]
         , "Text"
         , CharacterEncoding -> "UTF8"
         ]
Out[11]= $CharacterEncoding::utf8: The byte sequence {240} could not be
interpreted as a character in the UTF-8 character encoding. >>
$CharacterEncoding::utf8: The byte sequence {160} could not be
interpreted as a character in the UTF-8 character encoding. >>
$CharacterEncoding::utf8: The byte sequence {174} could not be
interpreted as a character in the UTF-8 character encoding. >>
General::stop: Further output of $CharacterEncoding::utf8 will be suppressed
during this calculation. >>
ð ®

.但我们看到原始问题中报告的故障。

UTF-16怎么样?UTF-16不在有效字符编码列表中,但"Unicode"在列表中。既然我们已经看到了数学似乎使用UTF-16作为其本机格式,让我们来试一试(使用带有字节顺序标记的大端UTF-16):

In[12]:= ImportString[
           ExportString[
             FromDigits[#, 16]& /@ {"fe", "ff", "d8", "42", "df", "9b"}
             , "Byte"
           ]
         , "Text"
         , CharacterEncoding -> "Unicode"
         ]
Out[12]= 𠮛

它起作用了。作为一个更完整的实验,我将问题re-encoded the cited text file转换为UTF-16并成功导入。

数学文档在这个问题上基本上没有提及。有趣的是,在MATHEMICA中提到Unicode似乎伴随着字符代码包含16位的假设。例如,请参阅Raw Character Encodings中对Unicode的引用。

由此得出的结论是,对于长度超过16位的代码,数学对UTF-8代码转换的支持是缺失/错误的。数学软件表面上的内部格式UTF-16似乎工作正常。因此,如果您能够重新编码文件,那么这是一种解决办法,您可以接受结果字符串实际上是UTF-16格式,而不是真正的Unicode字符串。

后记

在写完这篇回复后不久,我尝试重新打开包含它的数学笔记本。笔记本上出现的每一个有问题的字符都被抹去了,取而代之的是胡言乱语。我猜还有更多的Unicode错误需要解决,即使在数学8.0.1;)

这篇关于在数学中读取UTF-8编码的文本文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆