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。
解决方案
核心修正点
- 正确解析十六进制值为字节(而非仅转成UTF-16字符)
- 使用打印机对应的单字节扩展编码生成发送字节数组,替代
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
相关产品推荐
相关产品推荐

