我试图弄清楚为什么相同的源数据会给我两个不同的输出字符串,具体取决于我用来获取它的方法。
我有两个包含QuickBooks数据的CSV文件。一个是使用QuickBooks'创建的。内置报告功能,另一个是使用使用QuickBooks SDK的数据访问API创建的。在这两个CSV文件中,都有一个文本列,我应该可以将其用作关联所述文件中数据的键。
但是,在一个特定行中有一个特定字符,这两个文件似乎无法达成一致:
这导致了一个问题,因为我的代码认为两个字符串是不同的(它们在技术上是,但不应该是),因此无法匹配它们。我确信在某个地方某处肯定存在某种编码错误,但我找不到这两个字符之间的任何链接。
我不希望有人能够弄清楚究竟发生了什么,因为我们无法访问QuickBooks或API在幕后做什么。但是我希望有人可以告诉我为什么这个角色被错误翻译了。
答案 0 :(得分:0)
The problem is that they are (probably) encoding en-dash as U+0096 internally, which corresponds to the Windows-1252 byte (0x96) for en-dash, but in Unicode, it actually represents "Start of Guarded Area" special character.
For some backward compatibility reasons, web browsers convert this character to U+2013 for displaying on a webpage.
So there are two problems - wrong encoding on the side of QuickBooks and a confusing behavior of the browser, which is converting the character from windows-1252 to Unicode.
There are several related questions concerning this issue:
答案 1 :(得分:0)
据我所知,QuickBooks实际上是使用Windows-1252(这是从QB导出到文本文件时使用的编码)来存储和输出其数据的。但是,当通过基于SDK的API读取数据时,沿直线的某个位置Windows-1252代码被错误地解释为Unicode(无论是QB SDK,第三方API还是.NET Framework本身;我无法知道)。
这在大多数情况下都有效,因为两种编码之间的0到127(包括英语字母中的所有字母)的字符代码相同。但是从128开始,这两种方案有所不同,因此Windows-1252中的150表示“连字符”,而在Unicode中则表示“保护区开始”。
为此,我使用了以下代码:
Dim Builder As New Text.StringBuilder(Input)
For i = 0 To Builder.Length - 1
Dim n = AscW(Builder(i))
If n > 127 AndAlso n < 256 Then
Dim b As Byte = n
Builder(i) = System.Text.Encoding.Default.GetChars({b})(0)
End If
Next
Return Builder.ToString
这将获取每个字符的字符代码(使用AscW
),并且如果代码介于127和256(排他)之间(255是Windows-1252中的最后一个字符),请使用Windows正确解释-1252编码,然后将其正确转换为Unicode。