En Dash和保护区角色的开始

时间:2018-05-18 00:38:01

标签: .net text character-encoding quickbooks

我试图弄清楚为什么相同的源数据会给我两个不同的输出字符串,具体取决于我用来获取它的方法。

我有两个包含QuickBooks数据的CSV文件。一个是使用QuickBooks'创建的。内置报告功能,另一个是使用使用QuickBooks SDK的数据访问API创建的。在这两个CSV文件中,都有一个文本列,我应该可以将其用作关联所述文件中数据的键。

但是,在一个特定行中有一个特定字符,这两个文件似乎无法达成一致:

  • 在QuickBooks中,角色具有破折号的视觉外观
  • 在由QuickBooks直接创建的CSV中,该字符将导出为短划线(U + 2013或十进制代码8211)
  • 但基于SDK的API从QuickBooks中读取它作为"开始保护区"字符(U + 0096或十进制代码150)。

这导致了一个问题,因为我的代码认为两个字符串是不同的(它们在技术上是,但不应该是),因此无法匹配它们。我确信在某个地方某处肯定存在某种编码错误,但我找不到这两个字符之间的任何链接。

我不希望有人能够弄清楚究竟发生了什么,因为我们无法访问QuickBooks或API在幕后做什么。但是我希望有人可以告诉我为什么这个角色被错误翻译了。

2 个答案:

答案 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)

鲁阿卡斯(rouckas)的回答提醒我,我确实确实解决了这个问题。他大体上是对的,但是问题与网络浏览器无关,所以我认为我将提供我所做的确切修复工作。

据我所知,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。