unity 串口数据第一个字节丢失_SAS下GB18030编码文本列因丢失字节而无法导出数据集的修复宏...

本文详细介绍了在SAS使用GB18030编码时遇到的丢失字节问题,导致数据无法正常导出。问题源于GB18030编码的文本数据不完整,出现半个汉字现象。通过手动修复和宏自动化修复策略,特别是针对GB18030编码特点分析,提供了一种尝试修复的方法。建议从数据源端解决乱码问题,同时给出了SAS宏的示例代码用于修复含有乱码的数据集。
摘要由CSDN通过智能技术生成

想使用宏可直接在文章第6部分的示例代码。

1.问题描述

SAS设置编码为GB18030,SAS/EG在显示或导出结果数据集时报错,报错信息为:“未能将数据从U_EUC_CN_CE转码为U_UTF8_CE编码,因为它包含SAS会话编码不支持的字符。请查看您的encoding=和locale= SAS系统选项,以确保它们能够接受您要处理的数据。在十六进制表示法中的一部分源字符串为:……”

2.原因分析

出现此类错误的原因,通常是SAS文本列没有足够的存储宽度,或是数据迁移脚本运用了错误的取子字符串逻辑,导致GB18030编码的文本数据不完整,出现了所谓“半个汉字”问题。由于GB18030编码设计的天然缺陷,当一段文本中出现ASCII范围以外的字符,且有字节缺失的情况下,文本部分或全部显示为乱码,且使用SAS/EG导出或显示时会报错。下图展示了正确文本丢掉首字节后的效果:

b5a97ae2b7bcc09cedae0585ab2ed67a.png

上图显示效果来自Windows自带的记事本,可以看出E03A因为E0首先被认为是一个GB18030汉字的首字节,但是因为E03A不是合法的GB18030编码,所以这两个字节被显示为?,随后从D1继续开始解析。也就是说,对MBCS的处理策略,是前边的字节来决定后边的字节,解析过程总是从左到右的。然而一旦前边有字节缺失,后续计划有可能被全部打乱,因为解析策略未曾假定字节有可能已损坏,也从不尝试从中间或后面去修复。

3.手动修复方法

对于此类问题,最简单粗暴的方法是drop掉整个出问题的列。另一种比较辛苦的方法,是在全部记录中只有少部分条目有问题的情况下,通过折半法反复试验来锁定第几行存在问题,但是这种方法工作的工作量非常大,效率非常低,如果出错不只一行,基本上是不可行的。

4.尝试自动修复的策略

首先,我们来看一下GB18030的编码特点,请看下图:

94a17e54b831909747ffc60c659d5263.png

GBK范围内的汉字,都采用GB18030的双字节编码,GB18030四字节部分含盖的是CJK Ext-B以及后的汉字,以及汉字以外的非ASCII字符,使用频率比较低。而从双字节来看,第一字节、第二字节都有可能是81-FE(这也是GB2312的范围,即最常用的汉字所占区域)。从码位空间看起来,就81-FE来说,双字节的第一字节和第二字节编码区域重合,单从数据范围来说,出现几率相等,一旦缺少某个字节后,似乎修复变成了不可能的任务。
但是,我们还有两方面的机会。

第一是,文本不一定完全是汉字组成的,一旦内部含有单字节的ASCII部分内容,则可确定字符边界:边界一边即使是坏的,边界的另一边还可以重新开始。

第二是,即使完全只有汉字,但是其实各个字节值的分布也是有一定特点的,比如文本中经常会有中文标点,特别是逗号“,”句号“。”的出现频率是非常之高的,而标点的第一字节多属A1或A3区,也就是某字节如果为A1,或A3,它很有可能是GB18030码某字符的开始字节。

综合考虑以上两项因素,逐字符分析一个已损坏的文本,也很可能修复大部分内容正常。实在无法修复的,至少可以将试图修复过程中的问题字节,强制改为某字符(一般推荐修复为?比较利于显示)。

通过梳理各种情况,我们得到以下表:

eed59d212b78e0468879c5aa5ddba969.png

上表中可以看出,一旦出现00-2F, 3A-3F, 7F, FF,则其肯定是单字节,其上一字节属于另一个字符的结束,下一个字节也属于另一个字符的开端。而80则也肯定是双字节的结束字节,其下一字节属于另一个字符的开端。

除了肯定是单字节的情况,且不考虑出现机率比较小的四字节部分(四字节的情况很多&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值