无法 trim 的空格 Non-breaking space
1. 场景描述
营销活动, 运营同学上传人群名单, 系统读取文件将人群落库, 有行数据混进了空格, 发奖失败.
account_no = ‘ 226610000XXXXXXXXXX’
排查代码, 感觉没什么问题,
private CrowdDataInfo constructCrowdData(CrowdConfigInfo crowdConfigInfo, String data, int rowNum) {
...
CrowdDataInfo crowdDataInfo = new CrowdDataInfo();
crowdDataInfo.setAccountNo(dataArray[0].trim());
crowdDataInfo.setAccountType(crowdConfigInfo.getAccountType());
crowdDataInfo.setCrowdNo(crowdConfigInfo.getCrowdNo());
...
return crowdDataInfo;
}
Debug trim() 函数源码, 发现并没有走到判断语句中, 显然, 我们应该碰到了假空格!!
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
1.1 分析 ‘ ‘ 和 ‘ ‘;
使用 python ord() 可以快速查出这两个空格的 Unicode 编号, 32 是普通的空格, 160 是特殊空格(unicode 编码是 \u00A0
)
本文经过 MarkDown 语法转义, 测试代码中 “固定空格” 请使用
Option + Space
打印, Command + v 拷贝出来的是普通空格.
>>> ord(' ')
32
>>> ord(' ')
160
# 等同于
>>> ord('\u00A0')
160
也可以使用 Javascript 来感受 “特殊空格”, 直接打开浏览器 Console
> normal_space = ' '
' '
> special_space = '\u00A0'
' '
> normal_space.charCodeAt(0)
32
> special_space.charCodeAt(0)
160
Java 语言直接输出字符的整形即可.
char ch=' ';
System.out.println((int)ch);
1.2 几种语言的去空格函数
经过测试, 脚本语言自带的去除空格函数, 能去掉 '\uu00A0'
空格:
- Java 无法
String.trim()
特殊空格 - PHP 无法
trim(String)
特殊空格 - Javascript
String.trim()
可以去除特殊空格 - Python
String.strip()
可以去除特殊空格
经过谷歌, 发现 Unicode 为 160 的字符被称作 “Non-breaking space”, 下面仔细介绍一下.
2. 什么是 No-breaking Space
No-breaking Space, 也被成为 Fixed Space 姑且翻译成”固定空格”, 经常出现在 HTML 与 office 软件中. 前端同学会非常熟悉, 这货就是 ' '
.
2.1   和普通空格的区别:
多个空格, 在 html 中会被合并成一个,   不会被合并.
如下图所示:
2.1 如何打印固定空格
系统 | 输入方式 |
---|---|
Mac OS | Option + Space |
Windows 系统 | Ctrl + Alt + Space </br> Ctrl + Space </br> Alt + 0 + 1 + 6 + 0 |
3. 解决方式
既然知道该字符编码, 在 trim 之前, 用普通空格进行 replace 就可以了.
formattedString = originString.replace('\u00A0',' ').trim();
翻阅 JDK8 的文档, 自带了 [isWhitespace](http://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isWhitespace-char-)
, 总共有三个:
It is a Unicode space character (SPACE_SEPARATOR, LINE_SEPARATOR, or PARAGRAPH_SEPARATOR) but is not also a non-breaking space (‘\u00A0’, ‘\u2007’, ‘\u202F’).
处理字符串时, 转换成 char[] 遍历一遍也可以解决.
4. 参考文档
-
https://en.wikipedia.org/wiki/Non-breaking_space
-
http://htmlhelp.com/reference/charset/iso160-191.html
-
http://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isWhitespace-char-isWhitespace
-
https://unsplash.com/photos/Hv5vQ8AkbAs
blog comments powered by Disqus