在寻找一种从解析的HTML中修剪不间断空间的正确方法的同时,我首先偶然发现java的斯巴达定义String.trim()至少是正确记录的.我想避免明确列出符合修剪条件的字符,所以我假设在Character类上使用Unicode支持的方法可以帮我完成工作.
那时我发现Character.isWhitespace(char)明确排除了不间断的空格:
它是Unicode空格字符(
SPACE_SEPARATOR,LINE_SEPARATOR或PARAGRAPH_SEPARATOR),但不也是非打破空间('\u00A0','\u2007','\u202F').
这是为什么?
相应的.NET等价物的实现不那么有区别.
Ste*_*eod 22
Character.isWhitespace(char)老了.真的老了.Java早期的许多事情都遵循C的约定和实现.
现在,十多年后,这些事情似乎是错误的.考虑一下即使在Java的第一天和.NET的第一天之间已经发生了多大的事情.
Java力求100%向后兼容.因此,即使Java团队认为修复他们的初始错误并在从Character.isWhitespace(char)返回true的字符集中添加不间断空格也是好的,他们不能,因为几乎肯定存在软件依赖于当前实现的工作方式.
Jes*_*per 14
从Java 5开始,还有一种isSpaceChar(int)方法.那不是你想做的吗?
确定指定的字符(Unicode代码点)是否为Unicode空格字符.当且仅当字符被Unicode标准指定为空格字符时,才将字符视为空格字符.如果角色的常规类别类型是以下任何一种,则此方法返回true:...
Gré*_*eph 12
如上所述,isSpaceChar(int)将为OP提供跟踪答案.它看起来相当谨慎,但这种方法实际上可用于正则表达式.所以:
"X\u00A0X X".replaceAll("\\p{javaSpaceChar}", "_");
Run Code Online (Sandbox Code Playgroud)
将生成一个"X_X_X"字符串.它留给练习者读取正则表达式以修剪字符串.(带有一些标志的模式应该可以解决问题.)
我认为Java的实现比.NET更正确.不间断的空间本质上是一个非空白字符,看起来像一个.也就是说,如果你有字符串"foo"和"bar",并在它们之间放置任何传统的空白字符,你就会得到一个单词分隔符.然而,一个不间断的空间并没有打破这两个空间.
应该特别处理不间断空间的唯一时间是使用设计用于执行文本自动换行的代码.
出于所有其他目的,包括字数,修剪和沿着字边界的通用分割,不间断的空间仍然是空白.
任何一个非破坏性空间只是"看起来像"一个空间而不是一个空间的论点与Unicode的整个点相冲突,Unicode表示基于其含义的字符,而不是它们的显示方式.
因此,恕我直言,String.trim()的Java实现没有按预期执行,并且底层的Character.isWhitespace()函数有问题.
我的猜测是,Java实现者根据在控件中执行文本换行的需要编写了isWhitespace().他们应该将此函数命名为isWordWrappingBoundary()或更清晰的东西,并对trim()使用限制较少的空白测试.