2009-06-29 61 views
28

在寻找削减从解析的HTML非换空间之有道,我第一次无意中发现的String.trim() Java的斯巴达定义,至少适当的记录。我想避免明确列出符合剪裁的字符,所以我认为在Character类上使用Unicode支持的方法会为我完成这项工作。为什么java不打破空格不是空白字符?

这时候我才发现,Character.isWhitespace(char)明确排除非中断空格是:

它是Unicode空格字符(SPACE_SEPARATORLINE_SEPARATOR,或PARAGRAPH_SEPARATOR,但不也是非打破空间'\u00A0''\u2007''\u202F')。

这是为什么?

corresponding .NET equivalent的执行较少歧视。

回答

20

Character.isWhitespace(char)已老。真的很老。在Java中的初期做了很多事情,随后公约和实现从C

现在,十多年过去了,这些事情似乎是错误的。考虑一下它证明了事情到底有多远,甚至在Java的第一天和.NET的第一天之间。

Java力求100%向后兼容。所以,即使Java团队认为解决他们最初的错误并将不间断的空格添加到从Character.isWhitespace(char)返回true的字符集也是很好的,但他们不能,因为几乎可以肯定存在软件依靠当前的实施方式完全按照它的方式工作。

+3

关于向后兼容性:我同意,但没有理由不添加,例如Character.isWhitespaceNew(char)来捕获当前的情况。 – Jirka 2012-10-15 18:42:47

+13

那条路就是PHP。 – Eric 2012-11-20 18:32:56

+7

另一条路就在于Java。一种为追随者(从错误中吸取经验教训)开辟道路的语言,但为什么有人会自愿使用它,如果他们有其他选择,则超出我的理解范围。 – Eloff 2013-05-10 14:17:38

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. 

非换空间的功能应该是没有被分隔单词之间的视觉空间连字算法。

7

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

+4

非破坏性空间仍然是一个单词边界。在“非破坏性空间”中的“破”是指它应该如何解释**行**的目的 - 打破,而不是分词。 – richardtallent 2009-06-29 22:20:34

6

非打破空间应该特殊对待的唯一时间是设计用来执行文本的自动换行代码。

对于其他所有目的,包括字数,修整和沿字边界的通用拆分,非拆分空间仍为空格

的任何说法,非打破空间只是“看起来像”的空间,但不使用Unicode,它代表根据自己的含义的字符的整点一个冲突,而不是如何显示它们。

因此,IMHO,Java实现String.trim的()不按预期执行,和底层Character.isWhitespace()函数是错误的。

我的猜测是,Java实现者基于需要在控件中执行文本包装来编写isWhitespace()。他们应该命名这个函数isWordWrappingBoundary()或更清晰的东西,并使用trim()的限制较少的空白测试。

13

由于Java 5还有一个isSpaceChar(int)方法。这不是你想要的吗?

确定指定的字符(Unicode码点)是否是Unicode空格字符。一个字符被认为是一个空格字符,当且仅当它被Unicode标准指定为一个空格字符时。如果字符的常规类别的类型为以下任一此方法返回true:...

10

正如上面贴isSpaceChar(int)将提供OP与轨道的答案。它似乎相当谨慎地记录在案,但这种方法实际上是useable with regexes。 所以:

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

会产生 “X_X_X” 字符串。作为练习,读者可以使用正则表达式来修剪字符串。 (有一些标志的图案应该做的伎俩。)

2

当使用具有相同奇怪isWhitespace行为的apache公用函数StringUtils.isBlank()(和相关函数)时也要谨慎,即非破坏性空间被认为是非破坏性空间,空白。

相关问题