我有一个包含EM Dash(或—
HTML)的ASCII文件.十六进制值为0x97.当我们通过一个应用程序传递此文件时,它以UTF-8的形式到达,并将字符转换为0xC297,它是
HTML格式的.但是,当我们通过另一个应用程序传递此文件时,它将字符转换为0xE28094或—
.
什么会导致这些应用程序以不同方式转换这些字符 它可能是代码页设置吗?
是错的.使用数字字符引用时,该数字指的是Unicode代码点.对于低于256的数字,与ISO-8859-1中的代码点相同.在8859-1中,字符151属于"C1控制代码",而不是破折号或任何其他可见字符.
之所以产生混淆是因为字符151是Windows代码页1252(西欧)中的破折号.很多人认为cp1252与ISO-8859-1是一回事,但实际上并非如此:C1范围内的字符(128到159)是不同的.
第一个应用程序正在读取您的"ASCII"文件*作为ISO-8859-1,但实际上它可能是cp1252,你需要一种方法来提示应用程序关于它所期望的编码.
(*:如果文件中有顶部位设置字符,"ASCII"是用词不当.你可能意味着"ANSI",这实际上也是一个误称,但是在Windows世界中意味着"文本编码"在当前系统默认代码页".)
不是破折号,你的文字被错误地翻译成了破折号.
—
是em dash的HTML十进制实体.具体而言,它引用代表em破折号的Unicode代码点8212.
如果文件包含em破折号,则该文件不是ASCII.ASCII字符仅编码为十进制范围0 - 127,而em破折号不是可由ASCII编码表示的字符.如果你将em破折号存储为0x97(十进制151),你可能有一个ANSI文本文件(又名Windows代码页1252(w-1252)).
你的第一个应用......
数据以w-1252编码的em破折号开始.在w-1252中,em dash映射到十进制值151(十六进制为0x97,二进制为10010111).
在某些时候,em破折号由代码处理,该代码认为文件中的字节是iso-8859-1编码文本.当该代码将0x97解释为字符串/ char时,它根据iso-8859-1编码将0x97映射到字符.在iso-8859-1中,0x97映射到char"守卫区域的末端".
接下来,代码认为是"守卫区域结束"控制字符串的字符串被编码为utf-8.以utf-8编码的"保护区末尾"是双字节序列:0xC2 0x97.
你的第二个应用......
文本文件被正确解释为w-1252,因此0x97被识别为em dash,它被正确编码为utf-8中的em dash:0xE2 0x80 0x94.
是什么影响了这种行为
不确定你是在处理网络应用程序还是什么,但概念应该是相同的,无论它是什么.我们在Web应用程序中使用相同的0x97-> 0xC297方案,人们将数据输入到表单中.我发现网页的字符集被声明为iso8859-1,浏览器处理w1252字符的最佳方法是将它们作为iso字节发送,而不提醒用户或服务器.服务器接收数据认为它是iso并转换为utf-8,导致0xC297.
基本上,当应用程序触摸文本时,需要告知文本是如何编码的,否则它可能会回退到系统默认值.如果发生这种情况,您将面临数据损
根据HTML4规范的字符实体引用,emdash是— (U + 2014).
ASCII文件不能包含字符0x97,因为ASCII字符集的范围仅为0x00到0x7F.因此,您的文件不是ASCII,而是一些其他单字节编码.例如,windows-1250编码的em-dash为0x97.
如果应用程序使用除用于创建文件的编码之外的其他编码来解码文本文件,则任何高于0x7F的字符都将是错误的.
在unicode中,em-dash的字符代码为0x2014或十进制的8212.
Unicode字符'EM DASH'(U + 2014)
在例如使用windows-1250作为编码的网页中,代码
将呈现为em-dash:
em-dash