当前位置: 首页 > news >正文

教人如何做吃的网站/如何做好企业推广

教人如何做吃的网站,如何做好企业推广,优惠的网站快排公司电话,企业解决方案公司有哪些想使用宏可直接在文章第6部分的示例代码。1.问题描述SAS设置编码为GB18030,SAS/EG在显示或导出结果数据集时报错,报错信息为:“未能将数据从U_EUC_CN_CE转码为U_UTF8_CE编码,因为它包含SAS会话编码不支持的字符。请查看…

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

1.问题描述

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

2.原因分析

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

c4a58900e7e244d4b3b9816f1e6c7259.png

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

3.手动修复方法

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

4.尝试自动修复的策略

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

356cb4b04b8174a1c6f9c71616233a0c.png

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

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

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

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

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

74d13859c12e9a97fb30f184e2cb4390.png

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

除了肯定是单字节的情况,且不考虑出现机率比较小的四字节部分(四字节的情况很多,会使分析变得特别复杂),对于第二条思路,我们主要需要分析某一串连续的81-FE组成的字节中,从1开始进行位置编号,对于整个文本中,奇数位置上和偶数位置上出现某些特别字节的统计,可以帮助我们尝试是否发生了字节丢失(有误判的可能)。通常一些文字材料的统计,目前暂且总结出当出现以下字节:

A1,A3,B0-B9,BB-BE,C0,C1,C3,C7,C8,CA,CC-CF,D1-D7

时,这些字节更有可能是双字节的首字节部分。

综合以上两条策略,我制作了一个SAS宏分享给大家,它可对数据集中指定,或全部文本字段,试图进行修复,代码见本文第6部分。

5.建议从源端解决乱码的问题

以上修复的宏,毕竟也不是尽善尽美,不仅增加了麻烦,还有一定几率将正确的数据修复为错误的,治本的方法还需要从数据源端去解决错误的substr逻辑和宽度设置。

6.示例代码

为了修复含有乱码的数据集,请通过SAS数据步将问题数据集复制到另一处,并在数据步的set语句后加入fix_gb18030宏,如:

/*对work中有问题的test1数据集修复,结果存在work.test2中。*/ 
data work.test2; set work.test1; %fix_gb18030() 
run;

fix_gb18030宏有5个参数:

参数1:要修复的列,列名之间用空格分隔,如:

%fix_gb18030(a b c) /*修复a, b, c等3个文本列*/
%fix_gb18030() /*修复全部文本列*/

如果省略则默认修复所有列。注意,在知道肯定是哪几列出现问题时,尽量不要指定对所有列进行修复,除了速度更慢以外,也增大了将正确数据修复为错误数据的几率。

参数2:为了避免该宏使用的内部变量与数据集原有变量重名,而给内部变量加的前缀,通常该参数请跳过,如:

%fix_gb18030(,abcde) /*前缀为abcde*/
%fix_gb18030() /*前缀为fix_gb18030_*/

参数3:对于错误数据存在字符串首字节就是某汉字第2个字节的情况,第3个参数设置为1修复效果会更好些,其他情况下请采用默认值(即0)。

参数4:待修复格列的最大宽度,默认为1000。

参数5:是否将修正信息输出到SAS日志,为1输出,默认为0不输出。

SAS代码:

%macro fix_gb18030(cols_list,pre,fix_lost_first_half,max_length,putlog);
%if %length(&cols_list.)=0 %then %let cols_list=_character_;
%if %length(&pre.)=0 %then %let pre=fix_gb18030_;
%if %length(&fix_lost_first_half.)=0 %then %let fix_lost_first_half=0;
%if %length(&max_length.)=0 %then %let max_length=1000;
%if %length(&putlog.)=0 %then %let putlog=0;
array &pre.cols{*} &cols_list.;
length &pre.s $&max_length.;
%if &putlog.=1 %then %do;
length
&pre.err_obs $15 &pre.err_col_name $37
&pre.err_old_hex &pre.err_new_hex $%eval(&max_length.*2+8)
&pre.err_new_str $%eval(&max_length.+8);
drop &pre.err_obs &pre.err_col_name &pre.err_old_hex &pre.err_new_hex &pre.err_new_str;
%end;
length &pre.b0 &pre.b1 &pre.b2 &pre.b3 &pre.err_byte 3;
drop &pre.m &pre.s &pre.l &pre.p &pre.s0 &pre.s1 &pre.s0s1 &pre.g &pre.h &pre.i &pre.b0 &pre.b1 &pre.b2 &pre.b3 &pre.err_byte;
&pre.err_byte=03fx;
do &pre.g=1 to dim(&pre.cols);&pre.m=prxmatch('/^(?:[x00-x7f]|[x81-xfe](?:[x40-x7ex80-xfe]|[x30-x39][x81-xfe][x30-x39]))*$/',&pre.cols{&pre.g});if &pre.m=0 or &fix_lost_first_half.=1 then do;&pre.s0=0;&pre.s1=0;&pre.s0s1=1;&pre.l=lengthn(&pre.cols{&pre.g});&pre.p=&pre.l+1;do &pre.i=1 to &pre.l;&pre.b0=rank(substr(&pre.cols{&pre.g},&pre.i,1));if 081x<=&pre.b0<=0fex then do;if &pre.b0 in (0a1x,0a3x,0c0x,0c1x,0c3x,0c7x,0c8x,0cax) or 0b0x<=&pre.b0<=0b9x or 0bbx<=&pre.b0<=0bex or 0ccx<=&pre.b0<=0cfx or 0d1x<=&pre.b0<=0d7x thenif &pre.s0s1=0 then &pre.s0+1;else &pre.s1+1;&pre.s0s1=mod(&pre.s0s1+1,2);end;else if 000x<=&pre.b0<=02fx or 03ax<=&pre.b0<=03fx or &pre.b0=07fx or &pre.b0=0ffx then do;&pre.p=&pre.i;&pre.i=&pre.l;end;else if 040x<=&pre.b0<=07ex or &pre.b0=080x then do;&pre.p=&pre.i+1;&pre.i=&pre.l;end;end;if &pre.m=0 or &fix_lost_first_half.=1 and &pre.s0>&pre.s1 then do;&pre.s=&pre.cols{&pre.g};&pre.cols{&pre.g}=' ';do &pre.h=1,2;if &pre.h=1 then do;&pre.l=&pre.p-1;if &fix_lost_first_half.=1 then do;if &pre.s0>&pre.s1 then do;&pre.i=2;&pre.b0=rank(substr(&pre.s,1,1));if 000x<=&pre.b0<=07fx then do;&pre.cols{&pre.g}=byte(&pre.b0);end;else do;&pre.cols{&pre.g}=byte(&pre.err_byte);end;end;else do;&pre.i=1;end;end;else do;&pre.i=1;end;end;else do;&pre.i=&pre.p;&pre.l=lengthn(&pre.s);end;do while(&pre.i<=&pre.l);&pre.b0=rank(substr(&pre.s,&pre.i,1));if 000x<=&pre.b0<=07fx then do;substr(&pre.cols{&pre.g},&pre.i,1)=byte(&pre.b0);&pre.i+1;end;else if &pre.b0=080x or &pre.b0=0ffx then do;substr(&pre.cols{&pre.g},&pre.i,1)=byte(&pre.err_byte);&pre.i+1;end;else if 081x<=&pre.b0<=0fex then do;if &pre.i+1>&pre.l then do;substr(&pre.cols{&pre.g},&pre.i,1)=byte(&pre.err_byte);&pre.i+1;end;else do;&pre.b1=rank(substr(&pre.s,&pre.i+1,1));if 040x<=&pre.b1<=07ex or 080x<=&pre.b1<=0fex then do;substr(&pre.cols{&pre.g},&pre.i,2)=byte(&pre.b0)||byte(&pre.b1);&pre.i+2;end;else if 030x<=&pre.b1<=039x then do;if &pre.i+2>&pre.l then do;substr(&pre.cols{&pre.g},&pre.i,2)=repeat(byte(&pre.err_byte),2);&pre.i+2;end;else if &pre.i+3>&pre.l then do;substr(&pre.cols{&pre.g},&pre.i,3)=repeat(byte(&pre.err_byte),3);&pre.i+3;end;else do;&pre.b2=rank(substr(&pre.s,&pre.i+2,1));&pre.b3=rank(substr(&pre.s,&pre.i+3,1));if 081x<=&pre.b2<=0fex and 030x<=&pre.b3<=039x then do;substr(&pre.cols{&pre.g},&pre.i,4)=byte(&pre.b0)||byte(&pre.b1)||byte(&pre.b2)||byte(&pre.b3);end;else do;substr(&pre.cols{&pre.g},&pre.i,4)=repeat(byte(&pre.err_byte),4);end;&pre.i+4;end;end;else do;substr(&pre.cols{&pre.g},&pre.i,2)=repeat(byte(&pre.err_byte),2);&pre.i+2;end;end;end;end;end;
%if &putlog.=1 %then %do;if &pre.s^=&pre.cols{&pre.g} then do;&pre.err_obs='Obs['||put(_n_,1.)||']';&pre.err_col_name='Col['||vname(&pre.cols{&pre.g})||']';&pre.err_old_hex='OldHex['||trimn(put(trimn(&pre.s),$hex.))||']';&pre.err_new_hex='NewHex['||trimn(put(trimn(&pre.cols{&pre.g}),$hex.))||']';&pre.err_new_str='NewStr"'||trimn(&pre.cols{&pre.g})||'"';putlog 'GB18030 Fixed:' &pre.err_obs &pre.err_col_name;putlog &pre.err_old_hex;putlog &pre.err_new_hex;putlog &pre.err_new_str;end;
%end;end;end;
end;
%mend fix_gb18030;%macro fix_gb18030_ds(src_ds,dst_ds,cols_list,pre,fix_lost_first_half,max_length,putlog);
data %if %length(&dst_ds.)=0 %then &src_ds.;%else &dst_ds.;;set &src_ds.;%fix_gb18030(&cols_list.,&pre.,&fix_lost_first_half.,&max_length.,&putlog.)
run;
%mend fix_gb18030_ds;data work.test1;length text1 $40;input text1$;select(_n_);when(1)substr(text1,37,1)=byte(32);/*最末字符为汉字且次字节丢失(替换为空格)*/when(2)substr(text1,37,1)=byte(64);/*最末字符为汉字且次字节替换为@*/when(3)substr(text1,9,1)=byte(32);/*首个汉字次字节替换为空格*/when(4)text1=substr(text1,2);/*首个字节丢失*/otherwise;end;datalines4;
GB18030编码下汉字易出现半个汉字的问题
GB18030编码下汉字易出现半个汉字的问题
GB18030编码下汉字易出现半个汉字的问题
编码下汉字易出现半个汉字的问题
;;;;data work.test2;set work.test1;%fix_gb18030()
run;data work.test3;set work.test1;%fix_gb18030(,,1)
run;
国家标准|GB 18030-2005​openstd.samr.gov.cn
37e42cb17fc71b0faa386d4c127ea680.png
http://www.lbrq.cn/news/1529641.html

相关文章:

  • dw建立网站之后怎么做/国外网站搭建
  • 家电网站建设方案/上海百度移动关键词排名优化
  • 万网域名网站建设/电商运营怎么自学
  • 电子政务门户网站建设的意义/seo教程百度网盘
  • 表单大师做网站/白度
  • 怎么样制作个网站/郑州网络营销公司
  • 李沧网站建设电话/网站推广公司
  • 网业升级坊问/小果seo实战培训课程
  • 武汉便宜的做网站公司/网站服务器怎么搭建
  • 如何利用github做网站/互联网销售平台
  • 江西有色建设集团公司 网站/个人免费网站申请注册
  • 做网站3年/北京网站优化多少钱
  • 西部数码空间的网站访问统计/中国万网域名注册官网
  • 新万网/伟哥seo博客
  • 网站技术维护/企业网络营销策划书范文
  • 可以做链接的网站/宁波seo推广服务
  • 做日签的网站/百度优化教程
  • 衡水提供网站制作公司报价/网络营销策划与推广
  • 北京网站建设北京/网站优化的方法与技巧
  • wordpress首页文章内容/在线seo推广软件
  • 青岛做网站大公司有哪些/免费发布产品信息的网站
  • 邳州城乡住房和城乡建设网站/网络整合营销4i原则是指
  • 黄埔网站建设/苏州seo关键词优化排名
  • 免费建设网站入驻/公众号seo排名优化
  • 工业产品设计就业/常用的seo查询工具
  • 英国网站域名/目前疫情最新情况
  • 网站专题怎么做/seo关键词排名软件
  • 吴苏南网站建设/宁波网站seo诊断工具
  • 网络公司手机网站模板/企业seo培训
  • 九宫格导航网站/网络营销的主要传播渠道
  • html基本元素
  • X00238-非GNSS无人机RGB图像卫星图像视觉定位python
  • 使用EasyExcel自定义导出表格
  • 最新AI赋能Python-GEE遥感云大数据分析、可视化与Satellite Embedding创新应用
  • SQL中对视图的操作命令汇总
  • element table 表格多选框选中高亮