You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB中替换字符串内十六进制编码为对应ASCII字符的问题

解决扩展ASCII字符的十六进制转码与TCP打印问题

问题背景

需要将字符串中[]包裹的十六进制值转换为对应ASCII字符(例如Help[2f]me[2f]with[2d]this[2e]question转成Help/me/with-this.question),但处理[84]、[81]这类扩展ASCII字符时,通过TCP发送给打印机后无法被正确识别。原代码使用Encoding.ASCII.GetBytes()转换字节,厂商反馈需启用VB的扩展ASCII相关设置。

问题根源

Encoding.ASCII仅支持0x00-0x7F范围内的标准ASCII字符,对于0x80及以上的扩展ASCII字符,会自动替换为?(0x3F),导致打印机无法识别正确的控制字符或扩展字符。打印机所指的“扩展ASCII”实际是单字节编码(如IBM 437、Windows-1252等),而非标准ASCII。

解决方案

核心修正点

  1. 正确解析十六进制值为字节(而非仅转成UTF-16字符)
  2. 使用打印机对应的单字节扩展编码生成发送字节数组,替代Encoding.ASCII

方案1:修正编码后的字符串转字节

此方法先将解析后的字符暂存为字符串,再用目标编码转字节,适合简单场景:

Dim input As String = "Hello[1B][84][01][81][84][85]World"
Dim expression As String = "\[(.*?)\]"

' 解析十六进制到字符(暂存为UTF-16字符,后续转目标编码)
Dim result As String = Regex.Replace(input, expression, Function(m)
                                                           Dim hexStr = m.Groups(1).Value
                                                           ' 直接转成Byte,确保扩展ASCII值不丢失
                                                           Dim byteVal As Byte = Convert.ToByte(hexStr, 16)
                                                           Return Convert.ToChar(byteVal)
                                                       End Function)

' 关键:使用打印机对应的扩展编码(示例为IBM 437,多数老式打印机通用)
' 若为Windows扩展ASCII,替换为Encoding.GetEncoding(1252)
Dim targetEncoding As Encoding = Encoding.GetEncoding(437)
Dim sendBytes() As Byte = targetEncoding.GetBytes(result)

TCPClientz.Client.Send(sendBytes)

方案2:直接构建字节数组(更可靠)

跳过字符串转换环节,直接拼接普通文本的字节和解析后的十六进制字节,避免编码映射问题:

Dim input As String = "Hello[1B][84][01][81][84][85]World"
' 正则匹配:普通文本 + 十六进制块,直到字符串结束
Dim expression As String = "(.*?)(?:\[([0-9A-Fa-f]{2})\]|$)"
Dim byteList As New List(Of Byte)()
' 目标编码,根据打印机型号调整(示例为IBM 437)
Dim targetEncoding As Encoding = Encoding.GetEncoding(437)

For Each match As Match In Regex.Matches(input, expression)
    ' 处理普通文本部分,转成目标编码字节
    If Not String.IsNullOrEmpty(match.Groups(1).Value) Then
        Dim textBytes = targetEncoding.GetBytes(match.Groups(1).Value)
        byteList.AddRange(textBytes)
    End If
    ' 处理十六进制部分,直接转成Byte加入列表
    If Not String.IsNullOrEmpty(match.Groups(2).Value) Then
        Dim hexStr = match.Groups(2).Value
        Dim byteVal As Byte = Convert.ToByte(hexStr, 16)
        byteList.Add(byteVal)
    End If
Next

Dim sendBytes() As Byte = byteList.ToArray()
TCPClientz.Client.Send(sendBytes)

注意事项

  • 确认打印机的具体编码:不同厂商的扩展ASCII标准可能不同(如IBM 437、IBM 850、Windows-1252),需查阅打印机手册或咨询厂商获取准确编码ID。
  • 避免使用Encoding.ASCII或默认的UTF-8,两者都会破坏扩展ASCII字符的原始字节值。

内容的提问来源于stack exchange,提问作者Ranjan Sapkota

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:36:32