MaxCompute中如何处理异常字符

Posted 阿里云云栖号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MaxCompute中如何处理异常字符相关的知识,希望对你有一定的参考价值。

背景

在处理数据时,当业务数据同步至MaxCompute后,会产生一些含异常字符的脏数据,比如字段中包含了一个不可见字符,在DataWorks中显示不出来,但在BI界面又会显示成其他字符,影响整体观感。这种情况,通常我们的解法是,将异常的字符洗掉,下面来介绍几种常见的处理异常字符的方法。

问题描述

定位

如下图,可以看到“异常name”和“正常name”的 length值 不同,多了个不可见字符,但是我们并不能看出来啥。后期做数据处理或数据展示可能成为一个难以定位的问题。

SELECT 
  name as 异常name,
  LENGTH(name) as 异常name长度,
  '北京'  as 正常name,
  LENGTH('北京') as 正常name长度
from tbl1 
where name RLIKE '北京';

结果:

小技巧

  • 我们可以通过在线Unicode编码转换工具,将数值粘贴过去,获取到对应的Unicode码。同理也可以获取其他异常字符的Unicode码,以便后续处理。
  • 输入异常 vs 正常的字符串,对比 Unicode 差异可以倒推不可见字符为“ \\u200b”

解决方案

  • 定位到问题后,回顾数据清洗的常规方案,想办法把消掉这种不可见字符
方案描述备注本case是否适用
trim()函数常规的首尾不可见字符处理适用首尾部的空格、tab、换行Yes
replace()函数定向剔除字符串适用于单个待替换的字符,多个需要层层嵌套Yes
正则替换函数定向剔除一类字符串通过正则匹配符,替换一类字符串Yes

方案1:trim() - 替换

效果如下:

  • 利用 trim() 函数将数值中的异常不可见字符替换为正常空值字符(不可见字符可通过在线Unicode编码转换工具Unicode转中文复制一下)
SELECT 
  name as 异常name,
  LENGTH(name) as 异常name长度,
  trim(name,'')  as 正常name,
  LENGTH(trim(name,'')) as 正常name长度
from tbl1 
where name RLIKE '北京';

结果:

方案2:replace() - 替换

效果如下:

  • 利用 replace() 函数将数值中的异常不可见字符替换为正常空值字符(不可见字符可通过在线Unicode编码转换工具Unicode转中文复制一下)
SELECT 
 name as 异常name,
 LENGTH(name) as 异常name长度,
 replace(name,'','')  as 正常name,
 LENGTH(replace(name,'','')) as 正常name长度
from tbl1 
where name RLIKE '北京';

结果:

方案4:正则表达式 - 替换

  • 使用函数一层一层替换会比较麻烦,目前MaxCompute支持通过正则表达式匹配出异常的字符
  • 只要筛选出了带有异常的一部分字符,再处理就方便很多了
  • 例如上文中的不可见字符,Unicode码为“\\u200b”,通过执行如下SQL
select id,name from tbl1 where name rlike '[\\\\x200b]';

结果返回:

  • 此时如果再用regexp_replace()函数可以替换掉这一部分含不可见字符的数值
-- regexp_replace()函数
SELECT 
 name as 异常name,
 LENGTH(name) as 异常name长度,
 regexp_replace(name, '[\\\\x200b]', '',0)  as 正常name,
 LENGTH(regexp_replace(name, '[\\\\x200b]', '',0)) as 正常name长度
FROM tbl1;

结果:

总结

针对于SQL中的不可见字符或者其他中文等异常字符,都可以使用方案3中的筛选方式筛出来,然后再做后续的替换或其他操作就可以了。

原文链接

本文为阿里云原创内容,未经允许不得转载。

以上是关于MaxCompute中如何处理异常字符的主要内容,如果未能解决你的问题,请参考以下文章

手把手教你完成MaxCompute JDBC自定义日志配置

实际JAVAWEB项目中如何处理异常消息

C#中如何处理异常?怎么使用try-catch语句?

python中如何处理一个字符串中的每一个字符

Preact 中如何处理“refs”?

请问JavaScript中如何处理数字和字符串相乘的情况?