excel - 如何在 Excel VBA 中将 UTF-8 转换为 UTF-16?
问题描述
据我所知,Excel 使用 UTF-16 来表示字符串文字。我从控制台(Mac)/文件(Windows)读取,在这两种情况下,字符编码都是混乱的。我必须找到一个适用于两个平台的解决方案,所以 ADO 流不是一个选项。我做了一些调试,我看到实际字节是:
字节 | 显示为 | 应该是 | 正确的字节 258,129 | Ă | △ | 193 258,356 | ĂŤ | Í | 205 313,176 | Ĺ° | Ű | 219 313,144 | Ĺ | Ő | 213 258,347 | Ăś | ü | 220 258,8211 | Ă– | Ø | 214 258,353 | Ăš | Ú | 218 258,8220 | Ă“ | Ó | 211 258,8240 | É | 埃| 201
(来自古老的匈牙利语测试短语ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP,其中包含我们所有的特殊字符)。我正在寻找一种算法,它可以在 Mac 和 Windows 上产生正确的字符串。谢谢!
解决方案
由于我必须解决这个问题,我想出了以下函数,它可以成功转换 128 到 255 之间的字符
Private Function utf8ToUTF16(ByVal strText As String) As String
Dim i&, l1%, l2%, l3%
For i = 1 To Len(strText)
l1 = Asc(Mid(strText, i, 1))
If i <> Len(strText) Then l2 = Asc(Mid(strText, i + 1, 1))
Select Case l1
Case 194
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l2): i = i + 1
Case 195
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l2 + &H40): i = i + 1
Case 197
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l2 + &HC0): i = i + 1
Case 203
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l2 + &H240): i = i + 1
Case 226
If l2 = 128 Then
l3 = Asc(Mid(strText, i + 2, 1))
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l3 + &H1F80)
i = i + 2
ElseIf l2 = 130 Then
l3 = Asc(Mid(strText, i + 2, 1))
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l3 + &H2000)
i = i + 2
End If
Case Else
utf8ToUTF16 = utf8ToUTF16 & Chr(l1)
End Select
Next i
End Function
现在将“ĂRVĂŤZTĹ°RĹ TĂśKĂ–RFĂšRĂ“GÉP”传递给此函数(从标准 UTF-8 编码文件中读取)将返回“ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP”。
- 注意:这肯定不是最有效的代码。每当我调用它时,我总是在尽可能短的字符串上使用它。目前我用它来解码 cURL 的结果,并传递整个 HTML 冻结它。
编辑
现在我有一些时间来清理这个。
Private Function utf8ToUTF16(ByVal strText As String) As String
Dim i&, l1&, l2&, l3&, l4&, l&
For i = 1 To Len(strText)
l1 = Asc(Mid(strText, i, 1))
If i + 1 <= Len(strText) Then l2 = Asc(Mid(strText, i + 1, 1))
If i + 2 <= Len(strText) Then l3 = Asc(Mid(strText, i + 2, 1))
If i + 3 <= Len(strText) Then l4 = Asc(Mid(strText, i + 3, 1))
Select Case l1
Case 1 To 127
l = l1
Case 194 To 223
l = ((l1 And &H1F) * 2 ^ 6) Or (l2 And &H3F)
i = i + 1
Case 224 To 239
l = ((l1 And &HF) * 2 ^ 12) Or ((l2 And &H3F) * 2 ^ 6) Or (l3 And &H3F)
i = i + 2
Case 240 To 255
l = ((l1 And &H7) * 2 ^ 18) Or ((l2 And &H3F) * 2 ^ 12) Or ((l3 And &H3F) * 2 ^ 6) Or (l4 And &H3F)
i = i + 4
Case Else
l = 63 ' question mark
End Select
utf8ToUTF16 = utf8ToUTF16 & IIf(l < 55296, WorksheetFunction.Unichar(l), "?")
Next i
End Function
我意识到,55295(D7FF)以上的字符不会出现,所以它会输出一个问号作为占位符。
推荐阅读
- react-native - 使用 Cmd 中的命令进行 react-native 安装错误
- ckeditor - 经典ckeditor 5中的PasteFromOffice选项
- javascript - 停止输入呼叫功能后
- php - 在相关表中保存数据 Symfony 4
- javascript - 节点的背景图像样式不适用于 SVG 图像
- android - Android 通知未按预期工作
- javascript - 如何使用 google map api 隐藏从标记中出现的弹出窗口?
- php - 我可以使用字符串调用 php 函数吗?
- junit - 返回枚举的方法的单元测试
- javascript - javascript数字字符串反向排序无法正常工作