String replace() 在 Java 中返回额外的空间

Posted

技术标签:

【中文标题】String replace() 在 Java 中返回额外的空间【英文标题】:String replace() returns extra space in Java 【发布时间】:2019-01-25 09:09:11 【问题描述】:

考虑:

System.out.println(new String(new char[10]).replace("\0", "hello"));

有输出:

hellohellohellohellohellohellohellohellohellohello 

但是:

System.out.println(new String(new char[10]).replace("", "hello")); 

有输出:

hello hello hello hello hello hello hello hello hello hello

这些多余的空间是从哪里来的?

【问题讨论】:

你应该遍历字符串并打印每个字符。 @Ferrybig 从来没有尾随空格。 OP的原始描述(可能)不正确。参见例如ideone.com/492Cml。 【参考方案1】:

短版

\0代表字符NUL,不等于空字符串""

加长版

    当您尝试使用空的char[10] 创建String 时:

    String input = new String(new char[10]);
    

    这个String 将包含10 个NUL 字符:

    |NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|
    

    当您调用input.replace("\0", "hello") 时,NUL 值(\0)将被hello 替换:

    |hello|hello|hello|hello|hello|hello|hello|hello|hello|hello|
    

    当你调用input.replace("", "hello")时,NUL的值不会被替换,因为它与空字符串""不匹配:

    |hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|
    

【讨论】:

【参考方案2】:

这不是空格。这是您的 IDE/控制台显示 \0 字符的方式,new char[10] 默认填充。

你没有用任何东西替换\0,所以它保留在字符串中。而使用.replace("", "hello"),您只替换空字符串""。重要的是 Java 假定 "" 存在于:

字符串的开头, 字符串结束, 在每个字符之间

因为我们可以通过以下方式获得"abc"

"abc" = "" + "a" + "" + "b" + "" + "c" + ""`;
      //^          ^          ^          ^

现在.replace("", "hello") 将每个"" 替换为"hello",因此对于长度为10 的字符串,它将放置额外的11 hellos(不是10),而不修改\0,它将像空格一样显示在您的输出中。


也许这会更容易掌握:

System.out.println("aaa".replace("", "X"));
让我们将每个"" 表示为|。我们会得到"|a|a|a|"(注意有4个|) 因此将"" 替换为X 将导致"XaXaXaX"(但在您的情况下,您的控制台将使用看起来像空格的字符而不是a 打印\0

【讨论】:

【参考方案3】:

char的默认值为\u0000,也可以表示为\0。所以你的new char[10] 包含 10 个\0s。

在第一条语句中,您清楚地将\0 替换为"hello"。但是在第二个语句中,您省略了默认值。您的 IDE 输出选择显示为空格。

【讨论】:

【参考方案4】:

说明

您正在使用方法String#replace(CharSequence target, CharSequence replacement) (documentation)。

如果使用空的目标字符序列replace("", replacement) 调用,它将不替换源中的元素,而是插入之前的替换每个字符。

这是因为"" 匹配字符之间的位置,而不是字符本身。所以中间的每个位置都会被替换,即插入replacement

例子:

"abc".replace("", "d") // Results in "dadbdcd"

你的字符串在每个位置只包含char的默认值,它是

\0\0\0\0\0\0\0\0\0\0

因此使用该方法会导致:

hello\0hello\0hello\0hello\0hello\0hello\0hello\0hello\0hello\0hello\0

显示

您的控制台可能将字符\0 显示为空格,而实际上它不是空格,而是\0

如果我在不同的控制台中试用您的代码,我会得到:

确认字符确实不是空格,而是不同的东西(即\0)。

【讨论】:

replace("", ...) 也在字符串末尾插入替换。参见例如ideone.com/492Cml.

以上是关于String replace() 在 Java 中返回额外的空间的主要内容,如果未能解决你的问题,请参考以下文章

String replace() 在 Java 中返回额外的空间

Java:String.replace(regex, string) 从 XML 中删除内容

JAVA中string.replace和string.replaceAll的区别及用法

JAVA中string.replace和string.replaceAll的区别及用法

java replace方法

JAVA中string.replace()和string.replaceAll()的区别及用法