35

测试别人的代码,我注意到一些 JSP 页面打印了时髦的非 ASCII 字符。深入了解源代码,我发现了这个花絮:

// remove any periods from first name e.g. Mr. John --> Mr John
firstName = firstName.trim().replace('.','\0');

用空字符替换字符串中的字符甚至在Java中也有效吗?我知道这'\0'将终止一个 C 字符串。这会是时髦角色的罪魁祸首吗?

4

5 回答 5

90

用空字符替换字符串中的字符甚至在Java中也有效吗?我知道 '\0' 将终止一个 c 字符串。

这取决于你如何定义什么是有效的。它是否将所有出现的目标字符替换为'\0'? 绝对地!

String s = "food".replace('o', '\0');
System.out.println(s.indexOf('\0')); // "1"
System.out.println(s.indexOf('d')); // "3"
System.out.println(s.length()); // "4"
System.out.println(s.hashCode() == 'f'*31*31*31 + 'd'); // "true"

一切对我来说似乎都很好!indexOf能找到它,它算作长度的一部分,它的哈希码计算值为0;一切都由 JLS/API 指定。

如果您希望用空字符替换一个字符会以某种方式从字符串中删除该字符,那么它不起作用。当然,它不是那样工作的。空字符仍然是字符!

String s = Character.toString('\0');
System.out.println(s.length()); // "1"
assert s.charAt(0) == 0;

如果您希望空字符终止字符串,它也不起作用。从上面的片段中可以明显看出,但在 JLS 中也明确规定了这一点(10.9。字符数组不是字符串):

在 Java 编程语言中,与 C 不同,数组 ofchar不是 a String,并且 aString和数组都不char是由 '\u0000' (NUL 字符)终止。


这会是时髦角色的罪魁祸首吗?

现在我们谈论的是完全不同的事情,即字符串是如何在屏幕上呈现的。事实是,即使是“Hello world!” 如果你使用 dingbats 字体会看起来很时髦。一个 unicode 字符串在一种语言环境中可能看起来很时髦,但在另一种语言环境中则不然。即使是正确渲染的包含汉字的 unicode 字符串,对于来自格陵兰岛的人来说仍然可能看起来很时髦。

也就是说,不管怎样,空字符可能看起来很时髦;通常它不是您要显示的字符。也就是说,由于空字符不是字符串终止符,Java 完全能够以一种或另一种方式处理它。


现在要解决我们假设的预期效果,即从字符串中删除所有句点,最简单的解决方案是使用replace(CharSequence, CharSequence)重载。

System.out.println("A.E.I.O.U".replace(".", "")); // AEIOU

这里replaceAll也提到了解决方案,但这适用于正则表达式,这就是为什么您需要转义点元字符的原因,并且可能会更慢。

于 2010-03-26T13:38:02.093 回答
7

应该可能改为

firstName = firstName.trim().replaceAll("\\.", "");
于 2010-03-26T12:51:52.513 回答
5

我认为应该是这样。要擦除字符,您应该replace(".", "")改用。

于 2010-03-26T12:49:50.300 回答
4

用空字符替换字符串中的字符甚至在Java中也有效吗?

不。

这会是时髦角色的罪魁祸首吗?

很有可能。

于 2010-03-26T12:49:23.123 回答
2

这确实会导致“时髦的字符”:

System.out.println( "Mr. Foo".trim().replace('.','\0'));

产生:

Mr[] Foo

在我的 Eclipse 控制台中,其中 [] 显示为一个方框。正如其他人发布的那样,使用String.replace().

于 2010-03-26T12:53:22.343 回答