MySQL 5.7 记一次特殊空格c2a0的数据清洗

问题描述

数据已经通过trim()函数清洗前后空白,但是人工核对的时候还是发现了带有空白的字符,例如'fsmt2017 '

排查过程

1. 通过hexdump查看16进制编码

有问题的空格,复制过来的

MacBook-Pro-4:~ booboo$ echo 'fsmt2017 ' > test.a

手动敲击的空格space

echo 'fsmt2017 ' > test.b

通过hexdump查看16进制编码

MacBook-Pro-4:~ booboo$ hexdump -c test.a
0000000 f s m t 2 0 1 7 ? ? \n
000000b
MacBook-Pro-4:~ booboo$ hexdump -C test.a
00000000 66 73 6d 74 32 30 31 37 c2 a0 0a |fsmt2017...|
0000000b
MacBook-Pro-4:~ booboo$ hexdump -C test.b
00000000 66 73 6d 74 32 30 31 37 20 0a |fsmt2017 .|
0000000a

异常空格:

  • 看上去为空白的部分用hexdump -c查出来是乱码?
  • 16进制编码为c2a0

正常空格:

  • 16进制编码为20

hexdump命令帮助

hexdump:查看一些二进制文件的内容,比如二进制文件中包含的某些字符串。可以将二进制文件转换为ASCII、10进制、16进制或8进制进行查看。

-b 每一字节以八进制显示,一行共16个字节,一行开始以十六进制显示偏移值;
0000000 177 105 114 106 002 001 001 000 000 000 000 000 000 000 000 000
-c 每一字节以ASCII字符显示,其余同上;
0000000 177 E L F 002 001 001 \0 \0 \0 \0 \0 \0 \0 \0 \0
-C 每一字节以16进制显示,一行共16个字节,尾部附加16个相应的ASCII字符;
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
-n 只解释指定长度字节
单位:默认十进制,0x或0X开头则为16进制,0开头则为8进制。默认为字节,b则为512字节,k则为1024字节,m则为1048576字节

-d 双字节十进制显示
-o 双字节八进制显示
-v 去除中间显示的“*”字符
-x 双字节十六进制显示
-e 格式化参数

2. 对比中英文空格编码

对比表格 异常空白 异常空白 正常空白
字符 Â
Unicode编码10进制 194 160 32
Unicode编码16进制 c2 a0 20

3. 确定原因

C2A0是网页中常用的全角空格&nbsp。用户从其他网页上拷贝了一段包含此字符的字符串,复制到业务网站界面时,显示是正常的空白,
但实际上在数据库中存放的字符已经是一个异常的空白,无法通过trim()函数进行清洗。

4. 解决方法

  1. 将所有的异常空白替换为正常空白;
  2. trim()将前后空白删除。
-- c2a0 特殊字符
-- 0xC2 0xA0
-- 异常空白无法直接清洗
select trim('fsmt2017 ');
-- 先进行替换再清洗
select 'fsmt2017 ' ori, replace('fsmt2017 ',' ',' ') space,trim(replace('fsmt2017 ',' ',' ')) trim_result;

参考文章 https://www.cnblogs.com/lixiuke/p/9996504.html