C# 使用Encoding.UTF8.GetString转码出现�字符无法替换问题求助
�字符的本质
这个是Unicode标准定义的替换字符(U+FFFD),当解码器读取到不符合当前编码规则的无效字节序列时,就会自动插入这个字符作为无法识别内容的占位符。你遇到的每两个字符之间都出现占位符的情况,90%以上的可能性是你用错了解码编码:你的原始字节流大概率是UTF-16(双字节编码)格式,而非你用的UTF-8,ASCII字符在UTF-16中会用「字符字节+0x00」或者「0x00+字符字节」的双字节存储,用UTF-8解码时这些单独的0x00或者错位的字节会被判定为无效序列,就会生成你看到的�。
为什么Replace无法生效
你在界面上看到的�只是渲染层的显示效果,实际底层的无效内容不一定是U+FFFD字符:比如你用UTF32解码出来的空白方块,实际可能是不可打印的NULL字符(U+0000)或者其他控制字符,渲染时被替换成了占位符,你直接搜索替换U+FFFD当然匹配不到对应内容。
解决方案
优先方案:使用正确的编码解码
你先替换编码尝试解码,大概率直接能得到完全正常的结果,不需要清理任何字符:
// 尝试小端序UTF-16(Windows平台默认的Unicode编码) var obInstruction = Encoding.Unicode.GetString(ob.Bits); // 上面不行的话试大端序UTF-16 // var obInstruction = Encoding.BigEndianUnicode.GetString(ob.Bits);
备选方案:清理无效字符
如果确实无法确认原始编码,需要清理无效/不可打印字符,可以用下面两种方式实现类似Power Query中Text.Clean的效果:
- 解码时直接忽略无效字节,不生成替换字符:
// 初始化编码时配置无效序列直接丢弃,不插入替换字符 var encoding = Encoding.GetEncoding("UTF-8", new EncoderReplacementFallback(string.Empty), new DecoderReplacementFallback(string.Empty)); var obInstruction = encoding.GetString(ob.Bits);
- 对已解码的字符串过滤不可打印字符:
// 字符串扩展方法,可根据需求保留需要的控制字符(比如换行、制表符等) public static string CleanInvalidChars(this string input) { if (string.IsNullOrEmpty(input)) return input; return new string(input.Where(c => !char.IsControl(c) && c != '\ufffd').ToArray()); } // 调用示例 var obInstruction = Encoding.UTF8.GetString(ob.Bits).CleanInvalidChars();
内容的提问来源于stack exchange,提问作者NamelessCosmicDust
相关产品推荐
相关产品推荐

