【问题标题】:Split string displays more character拆分字符串显示更多字符
【发布时间】:2015-02-12 19:30:35
【问题描述】:

我正在尝试拆分一个 17 字节的字符串,但是当我显示长度时它显示为 18。

String s1 = "{{ (( 4 + 5 )) }}";
String[] s2 = s1.split("");
System.out.println("length = " + s2.length);

【问题讨论】:

  • 在我的机器上:length = 17
  • length = 17 我也是
  • 我看到你所有的结果都是一致的。不知道我的编辑器有没有问题。
  • 我的意思是,如果您仍然遇到问题,为什么不 System.out.println 每个字符作为健全性检查?
  • 我这样做了,但由于某种原因,我在第一个列表项上得到了一个空格,不知道为什么会得到它

标签: java


【解决方案1】:

它在 Java 7 中显示了 18 的长度,因为被空字符串分割会在每个字符的前后找到一个分隔符。

 { {   ( (...
^ ^ ^ ^ ^ 

在 Java 7 中,trailing empty strings are discarded

如果 n 为零,则该模式将被应用尽可能多的次数,数组可以有任意长度,并且尾随的空字符串将被丢弃。

所以,在 Java 7 中,我得到了 18 的长度,因为尾随的空字符串被丢弃,但前导的空字符串没有被丢弃。

包括这一行

System.out.println(Arrays.toString(s2));

产生这个输出

[, {, {,  , (, (,  , 4,  , +,  , 5,  , ), ),  , }, }]

前导空字符串。

但是,在 Java 8 中,this statement is now included in the Javadocs

如果在此字符串的开头存在正宽度匹配,则在结果数组的开头包含一个空的前导子字符串。但是,开头的零宽度匹配永远不会产生这样的空前导子字符串。

它不在 Java 7 javadocs 中。

似乎已更改行为以消除零宽度匹配的前导字符串,本问题就是这种情况。

Java 8 输出:

[{, {,  , (, (,  , 4,  , +,  , 5,  , ), ),  , }, }]

[ 的数组打印后的开头, 现在消失了,长度现在是17

【讨论】:

  • 非常感谢您的澄清
【解决方案2】:

看起来您使用的是 Java 7。

在 Java 8 之前 "foo".split("") 在每个空字符串上拆分,但由于空字符串存在于每个字符之前和之后,我们在这些地方有效拆分(标记为 ||f|o|o| 生成第一个数组,如 ["", "f","o","o",""] .

现在,由于split 还删除了空尾字符串"foo".split(""),因此返回了["", "f","o","o"],并且您看到它在开始时有一个空字符串。

您可以通过在字符串开头以外的地方进行拆分来解决此问题。您可以使用split("(?<!^)") 使用正则表达式和负向后视(?<!...),它使用^ 表示的字符串的开头。

String[] s2 = s1.split("(?<!^)"); //for "foo" this split returns ["f","o","o"]

其他人无法重现您的问题,因为这种行为在 Java 8 中发生了变化:Why in Java 8 split sometimes removes empty strings at start of result array?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多