在日常的数据分析处理工作中,不可避免的经常会和中文字符串打交道。如果数据中有乱码,该如何处理?...

烦人的问题

在日常工作中,使用SAS进行数据处理是很正常的事情,不可避免的经常会和中文字符串打交道。不知道各位在使用EG的过程中,打开数据集查看数据的时候,有没有遇到过以下问题?

(虽然我也只是偶尔遇到,但已经被折磨好几年!)

SAS Enterprise Guide 5.1

SAS Enterprise Guide 6.1

SAS Enterprise Guide 7.1

不同的版本提示的错误形式不完全一样,但出现的原因却是一模一样的(下面有情景再现的过程)。仔细查看,不难发现真正的错误信息都是一样的,主要是:

“Failed to transcode data from U_EUC_CN_CE to U_UTF8_CE encoding because

it contained characters wihch are not supported by your SAS session

encoding. Please review your encoding= and locale= SAS system options to

ensure that they can accommodate tje data that you want to process.”

这段话是什么意思呢?其实就是上面EG 7.1版本的错误提示的中文描述。简而言之,就是告诉你数据中有无法处理的编码数据。

问题的严重性

出现这个问题,仅仅是不能打开查看数据吗?不是!如果出现这个问题,意味着你基本不能用这个数据进行后续的分析了。只要进行的处理或者分析涉及到该有问题的字段就会提示上面的这个错误信息,阴魂不散,挥之不去。

怎么办

最简单粗暴的办法就是不用图形化的工具EG,用最经典的Base工具就没有这个问题了,一劳永逸。而有时候没法不用EG的时候怎么办?比如我是用EG连着SAS服务器进行处理的,该怎么办?

至于为什么EG会出现这个问题,而Base界面没有这个问题呢?主要是因为软件的底层设计而导致的,这个编码问题说大不大,说小不小;忽略了就可以正常使用,如果不忽略,那么它就是一个问题。下面会对这个问题进行再现,剖析其原因,你就明白了。

问题重现

当我第一次遇到这个问题的时候,想不明白,就去google搜索错误信息,找到的文档资料基本都是说编码或者地区的设置问题。意思就是说数据的编码跟现有的SAS环境的编码不一致,也就是上面错误信息当中提示的。要你通过option

encoding= locale=;

修改到正确的编码及地区,就可以解决问题了。可是我的环境是没有任何问题的,数据也是同样的环境生成的。经过了几次的研究,最后搞清楚了,这个问题是由于中文被截断而导致的。

(下文需要有一定的IT基础知识,不懂的童鞋,可度娘有关数据存储、数据编码方面的知识;只要大概明白数据是怎么在计算机中存储及还原的就OK了)

具体来说:在GBK编码中(SAS中文的默认编码方式),一个汉字是占两个字节。由于各种原因,在存储数据的时候某个汉字只存储了其中的一个字节,另一个字节丢失了。那么就导致这个字节没法还原,不知道是什么东西(因为少一个字节的信息)。所以才会有上面的错误提示:数据中包含当前SAS会话编码不支持的编码数据。

我们可以用下面简单的程序来再现这个问题(在EG中运行这段程序,在Base中是可以正常查看数据的,但只显示“你好”。)

data test;

length str $ 5;

str="你好啊";

run;

当运行完这段程序,打开test数据集查看的时候,就出现上面的错误信息:

“你好啊”三个汉字需要6个字节去存储,而str事先定义了长度为5个字节,这就导致只存储了2.5个汉字;而存储的这0.5个汉字信息由于没法显示,所以才导致上面提示的编码问题。

进一步来看看底层的信息(十六进制编码):

data _null_;

length str1 $ 5 str2 $ 6;

str1="你好啊";

str2="你好啊";

put str1 $hex12.;

put str2 $hex12.;

run;

日志信息:

从上面的日志信息可以看到,就是因为少存储了“A1”这个字节信息,导致“B0”这个字节无法解码,无法正常显示。

额外补充(懂的人就此略过):

汉字“你”的GBK编码,十进制为50403,十六进制为C4E3

汉字“好”的GBK编码,十进制为47811,十六进制为BAC3

汉字“啊”的GBK编码,十进制为45217,十六进制为B0A1有人可能会想:英文字符就是一个字节存储的,一个字节也能显示出来;为什么这里的一个字节就出问题了?

这就涉及到编码范围的问题了,英文字符是ASCII编码。通过查看标准的ASCII码表就可发现,最大的编码十进制为127,十六进制为7F;而B0是远大于7F的,超出了ASCII的编码范围,因此无法显示。

如果你够仔细,你就会发现,其实在EG的错误提示中,就包含了这段出问题的十六进制编码信息:c4 e3 ba c3 b0。

解决方案

问题的原因既然搞清楚了,那么如何解决的思路就很清晰了。说白了就是找出字符串中有中文截断的地方,然后将这半个汉字的信息直接删除就没问题了。

以前面生成的test数据为例,str的最后一个字节包含了半个汉字信息,只要将最后一个字节删掉就OK了。

data test2;

set test;

code_before=put(str,$hex10.);

str=substr(str,1,4);

code_after=put(str,$hex10.);

run;

如上所示,经过处理后,可以正常的显示数据了。

(注:code_after中最后一个字节“20”是空格的十六进制编码。字符变量中多余的字节,SAS默认用空格来填充。因此“你好”两个汉字占4个字节,剩余一个字节就是空格。)

虽然解决方法很清晰,想起来也很简单,但要实现起来还不是那么容易。上面的情况是特例,我们明显知道在哪个地方有问题,直接处理就OK。

但通常情况下,我们是不知道在字符串的具体哪个地方有截断,也不知道是哪些观测有截断的问题;而且每条观测中被截断的位置也不一定都一样,甚至也不知道截断的数据后面有没有其他字符数据。面对这么多不确定,该如何解决?

下面,提供一种思路,有兴趣的童鞋可以自由发挥,去解决这个问题。

解决思路

首先,GBK编码方案中,总体的编码是有范围的,从8140~FEFE。其中首字节在81~FE之间,尾字节在40~FE之间,剔除xx7F一条线;总计23940个码位,共收入21886个汉字和图形符号,其中汉字21003个,图形符号883个。

其次,ASCII编码的范围是从00~7F,共计128个码位,收入大小写英文字母、数字、符号、及特殊控制字符。其中可显示的编码范围为20~7E。

基于上面的这些信息,就可以从十六进制编码入手,逐个去判断识别,进而找到存在截断的位置,然后将其处理掉。记得要考虑以下多种情况:数据分析师培训

截断情况出现在字符串末尾

截断情况出现在字符串中间,且后面紧跟英文字母

截断情况出现在字符串中间,且后面紧跟完整的汉字

sas mysql乱码_在SAS中如何解决中文乱码问题相关推荐

  1. mysql在可视化软件navicat中如何解决中文乱码问题

    报错情况 https://blog.csdn.net/hanhanwanghaha宝藏女孩 欢迎您的关注! 欢迎关注微信公众号:宝藏女孩的成长日记 如有转载,请注明出处(如不注明,盗者必究) sql语 ...

  2. java web 中有效解决中文乱码问题-pageEncoding与charset区别, response和request的setCharacterEncoding 区别

    java web 中有效解决中文乱码问题-pageEncoding与charset区别, response和request的setCharacterEncoding 区别 参考文章: (1)java ...

  3. git status 显示中文和解决中文乱码

    git status 显示中文和解决中文乱码 文章目录 git status 显示中文和解决中文乱码 解决git status不能显示中文 解决git bash 终端显示中文乱码 通过修改配置文件来解 ...

  4. linux tomcat 日志乱码,Linux下TOMCAT中日志出现中文乱码

    红帽子AS4,其中TOMCAT为6.0. 结果TOMCAT中日志出现中文乱码 解决方法修改i18n: 最后的配置为: [root@linux etc]# more /etc/sysconfig/i18 ...

  5. java txt中文乱码,JAVA读取TXT文件 可解决中文乱码问题

    import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.I ...

  6. java项目ssh中文乱码_【SSH】Struts2处理中文乱码问题总结

    学了很久的java,接触SSH也有一段时间了,写成博文总是有点懒,最近在整理一些思绪,把SSH一点一滴放进博客里,以备以后改进,再学习.以我自己的了解,在进行struts开发的过程中,总也是出现很多的 ...

  7. java乱码base64_JavaScript BASE64算法实现(完美解决中文乱码)

    JavaScript 的 BASE64 算法 var BASE64={ enKey: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123 ...

  8. oracle utf-8中文乱码,修改Oracle字符集为UTF-8 解决中文乱码 oracle

    很多情况下,遇到数据库查询数据中文乱码,一般都是字符集的问题,下面记录一下oracle字符集的查看方法,并提供UTF-8字符集的修改方式. 1.查看数据库字符集 以下操作均在sqlplus或客户端中执 ...

  9. python爬虫的数据如何解决乱码_写爬虫时如何解决网页乱码问题

    实战讲解,文章较长,对爬虫比较熟悉的浏览翻看章节 2.3 获取新闻文本内容. 写爬虫时经常对网址发起请求,结果返回的html数据除了标签能看懂,其他的全部是乱码.大家如果对爬虫感兴趣,请耐心阅读本文, ...

  10. jquery 乱码 传参_jquery获取URL中参数解决中文乱码问题的两种方法

    从A页面通过url传参到B页面时,解析url参数可以用下面两种方法: 方法一:正则分析法 function getQueryString(name) { var reg = new RegExp(&q ...

最新文章

  1. 5.MYSQL存储过程的管理
  2. 计算机无法进入桌面怎么备份,无法进入系统如何正常备份数据?
  3. 辽宁活跃ip段_有泰国女排影子!激情辽宁女排,打出快乐排球,输了比赛赢了球迷...
  4. c cuda 指定gpu_GPU并行编程:熟练使用CUDA C语言
  5. 2018年AI专业最全报考指南:去哪学?怎么去?
  6. 隐藏/显示jeecg-boot 后端管理页面的右侧的系统设置
  7. Sutton 强化学习, 21 点游戏的策略蒙特卡洛值预测
  8. python获取a股报表数据_python获取A股基础数据
  9. 发票验真API开发文档
  10. 继电器rc吸收电路取值_RC吸收电路
  11. 上班划水,给男朋友做个数字炸弹游戏
  12. 玩转力扣 - LeetCode进度倒计数表
  13. (黑苹果镜像)macOS Ventura 13.0.1 (22A400)恢复版镜像
  14. 人民币持续升值,百姓感受渐深
  15. python读取pcd文件_(一)读取PCD文件
  16. 教你刷各大android手机应用市场下载排名
  17. CPen虚线无效问题
  18. ROS移植机器人小车:问题集(2)
  19. 网秦手机杀毒软件 v2.1 pocketpc _wm5.0 下载
  20. 【三维路径规划】基于matlab复杂三维地形的无人机路径规划【含Matlab源码 2171期】

热门文章

  1. 台灯c语言,Jya无线台灯C 告诉你如何重新定义光的含义
  2. vue项目中实现多语言 vue-i18n处理动态加载后端数据语言
  3. 一文讲解5G、互联网、物联网、大数据、人工智能的关系
  4. 【语义分割】3、用mmsegmentation训练自己的分割数据集
  5. Soul是一个基于兴趣、场景、算法搭建的“第三空间”?
  6. 免安装连接oracle,Oracle免安装PL/SQL连接
  7. hashmap怎么保证线程安全的方式
  8. 鉴权html5服务器,搭建web之 服务器鉴权失败,请确认服务器已启用密码鉴权并且账号密码正确?...
  9. xheditor 内容保存时 不转义html特殊字符,XHEditor使用文档(转载收藏)
  10. PS更换证件照背景色,并去除人物像边线