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

Pal*_*ndo 30 java unicode

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

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

它是Unicode空格字符(SPACE_SEPARATOR,LINE_SEPARATORPARAGRAPH_SEPARATOR),但不也是非打破空间('\u00A0','\u2007','\u202F').

这是为什么?

相应的.NET等价物的实现不那么有区别.

Ste*_*eod 22

Character.isWhitespace(char)老了.真的老了.Java早期的许多事情都遵循C的约定和实现.

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

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

  • 沿着这条路走下去就是PHP. (13认同)
  • 而另一条道路就在于Java.一种语言为那些接下来的人(从错误中吸取了教训)开辟了道路,但为什么有人会在有其他选择的情况下自愿使用它,这是我无法理解的. (7认同)
  • 关于向后兼容性:我同意,但没有理由不添加,例如,Character.isWhitespaceNew(char)来捕获当前情况. (3认同)
  • @Jirka好吧,他们确实添加了它,只不过它被称为Character.isSpaceChar(char); 但它不包括换行符 (2认同)

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"字符串.它留给练习者读取正则表达式以修剪字符串.(带有一些标志的模式应该可以解决问题.)

  • @zendu - 虽然不是很明显:1) https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#jcc :> 行为类似于 java 的类别.lang.Character boolean ismethodname 方法(不推荐使用的方法除外)可通过相同的 \p{prop} 语法使用,其中指定的属性具有名称 javamethodname。2) https://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#isSpaceChar(char) (2认同)

Mat*_*ush 7

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

  • 不间断的空间仍然是一个单词边界."非破坏空间"中的"破裂"指的是如何解释**行**的目的 - 破坏,而不是单词破坏. (4认同)

ric*_*ent 6

应该特别处理不间断空间的唯一时间是使用设计用于执行文本自动换行的代码.

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

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

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

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

  • String.trim()比那更糟糕.它只修剪ASCII控制字符,根本没有Unicode空格,无论是否破坏. (5认同)