为什么非破坏空间不是java中的空白字符?

时间:2009-06-29 21:10:24

标签: java unicode

在寻找一种从解析的HTML中修剪不间断空间的正确方法的同时,我首先偶然发现了java的简短String.trim()的定义,这至少是正确记录的。我想避免明确列出符合修剪条件的字符,所以我假设在Character类上使用Unicode支持的方法可以帮我完成工作。

那时我发现Character.isWhitespace(char)明确排除了不间断的空格:

  

它是一个Unicode空格字符(SPACE_SEPARATORLINE_SEPARATORPARAGRAPH_SEPARATOR但不是一个不间断的空格({{1} },'\u00A0''\u2007')。

为什么?

corresponding .NET equivalent的实施不那么具有歧视性。

7 个答案:

答案 0 :(得分:21)

Character.isWhitespace(char)已经过时了。真的老了。 Java早期的许多事情都遵循C的惯例和实现。

现在,十多年后,这些事情似乎是错误的。考虑一下,即使在Java的第一天和.NET的第一天之间,事情已经走了多远。

Java努力实现100%向后兼容。因此,即使Java团队认为修复他们的初始错误并在从Character.isWhitespace(char)返回true的字符集中添加不间断空格也是好的,他们不能,因为几乎可以肯定存在软件依赖于当前实现的工作方式。

答案 1 :(得分:14)

从Java 5开始,还有isSpaceChar(int)方法。那不是你想做的吗?

  

确定指定的字符(Unicode代码点)是否为Unicode空格字符。当且仅当字符被Unicode标准指定为空格字符时,才将字符视为空格字符。如果角色的常规类别类型是以下任何一种,则此方法返回true:...

答案 2 :(得分:12)

如上所述,isSpaceChar(int)将为OP提供回答的跟踪。它看起来相当谨慎,但这种方法实际上是useable with regexes。 所以:

    "X\u00A0X X".replaceAll("\\p{javaSpaceChar}", "_");

将生成“X_X_X”字符串。它留给练习者读取正则表达式以修剪字符串。 (带有一些标志的模式应该可以解决问题。)

答案 3 :(得分:7)

我认为Java的实现比.NET更正确。不间断的空间本质上是一个非空白字符,看起来像一个。也就是说,如果你有字符串“foo”和“bar”,并在它们之间放置任何传统的空白字符,你就会得到一个单词分隔符。然而,一个不间断的空间并没有打破这两个空间。

答案 4 :(得分:6)

应该特别处理不间断空格的唯一时间是设计用于执行文字换行的代码。

出于所有其他目的,包括字数,修剪和沿着字边界的通用分割,不间断的空格仍然是空白

任何一个非破坏性空间只是“看起来像”一个空间而不是一个空间的论点与Unicode的整个点相冲突,Unicode表示基于其含义的字符,而不是它们的显示方式。

因此,恕我直言,String.trim()的Java实现没有按预期执行,并且底层的Character.isWhitespace()函数有问题。

我的猜测是Java实现者根据在控件中执行文本换行的需要编写了isWhitespace()。他们应该将此函数命名为isWordWrappingBoundary()或更清晰的东西,并对trim()使用限制较少的空白测试。

答案 5 :(得分:2)

看起来方法名称(isWhitespace)与其功能(检测分隔符)不一致。如果你查看你引用的Javadoc页面中的完整字符列表,那么“分隔符”功能就相当清楚了:

* It is a Unicode space character (SPACE_SEPARATOR, LINE_SEPARATOR, or PARAGRAPH_SEPARATOR) but is not also a non-breaking space ('\u00A0', '\u2007', '\u202F').
* It is '\u0009', HORIZONTAL TABULATION.
* It is '\u000A', LINE FEED.
* It is '\u000B', VERTICAL TABULATION.
* It is '\u000C', FORM FEED.
* It is '\u000D', CARRIAGE RETURN.
* It is '\u001C', FILE SEPARATOR.
* It is '\u001D', GROUP SEPARATOR.
* It is '\u001E', RECORD SEPARATOR.
* It is '\u001F', UNIT SEPARATOR. 

非破坏空间的功能应该是不被连字算法分隔的单词之间的可视空间。

答案 6 :(得分:2)

使用具有相同奇怪StringUtils.isBlank()行为的apache commons函数isWhitespace(及相关函数)时也要小心,即不间断空格被视为非空白。