[英]Apache POI Anomalous Whitespace (Resolved: \u00A0 non-breaking space)
[英]Why is non-breaking space not a whitespace character in java?
在寻找一种从解析的HTML中修剪不间断空间的正确方法的同时,我首先偶然发现了java的String.trim()
的spartan定义,该定义至少是正确记录的。 我想避免明确列出符合修剪条件的字符,所以我假设在Character类上使用Unicode支持的方法可以帮我完成工作。
那时我发现Character.isWhitespace(char)明确排除了不间断的空格:
它是一个Unicode空格字符(
SPACE_SEPARATOR
,LINE_SEPARATOR
或PARAGRAPH_SEPARATOR
), 但也不是一个不间断的空格 ('\ '
,'\ '
,'\ '
)。
这是为什么?
相应的.NET等价物的实现不那么有区别。
Character.isWhitespace(char)
很旧。 真的老了。 Java早期的许多事情都遵循C的约定和实现。
现在,十多年后,这些事情似乎是错误的。 考虑一下即使在Java的第一天和.NET的第一天之间已经发生了多大的事情。
Java力求100%向后兼容。 因此,即使Java团队认为修复他们的初始错误并在从Character.isWhitespace(char)返回true的字符集中添加不间断空格也是好的,他们不能,因为几乎可以肯定存在软件依赖于当前实现的工作方式。
从Java 5开始,还有一个isSpaceChar(int)
方法。 那不是你想做的吗?
确定指定的字符(Unicode代码点)是否为Unicode空格字符。 当且仅当字符被Unicode标准指定为空格字符时,才将字符视为空格字符。 如果角色的常规类别类型是以下任何一种,则此方法返回true:...
如上所述, isSpaceChar(int)
将为OP提供跟踪答案。 它看起来相当谨慎,但这种方法实际上可用于正则表达式 。 所以:
"X\u00A0X X".replaceAll("\\p{javaSpaceChar}", "_");
将生成一个“X_X_X”字符串。 它留给练习者读取正则表达式以修剪字符串。 (带有一些标志的模式应该可以解决问题。)
我认为Java的实现比.NET更正确。 不间断的空间本质上是一个非空白字符,看起来像一个。 也就是说,如果你有字符串“foo”和“bar”,并在它们之间放置任何传统的空白字符,你就会得到一个单词分隔符。 然而,一个不间断的空间并没有打破这两个空间。
应该特别处理不间断空间的唯一时间是使用设计用于执行文本自动换行的代码。
出于所有其他目的,包括字数,修剪和沿着字边界的通用分割,不间断的空间仍然是空白 。
任何一个非破坏性空间只是“看起来像”一个空间而不是一个空间的论点与Unicode的整个点相冲突,Unicode表示基于其含义的字符,而不是它们的显示方式。
因此,恕我直言,String.trim()的Java实现没有按预期执行,并且底层的Character.isWhitespace()函数有问题。
我的猜测是,Java实现者根据在控件中执行文本换行的需要编写了isWhitespace()。 他们应该将此函数命名为isWordWrappingBoundary()或更清晰的东西,并对trim()使用限制较少的空白测试。
看起来方法名称( 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.
非破坏空间的功能应该是不被连字算法分隔的单词之间的可视空间。
使用具有相同奇怪的isWhitespace行为的apache commons函数StringUtils.isBlank() (及相关函数)时也要小心,即不间断空格被认为是非空白的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.