Java 字符串替换和 NUL(空值,ASCII 0)字符?

2022-09-01 06:21:49

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

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

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


答案 1

将字符串中的字符替换为空字符在 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"

对我来说,一切似乎都很好! 可以找到它,它算作长度的一部分,并且其哈希代码计算的值为0;一切都按照 JLS/API 的规定进行。indexOf

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

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

如果您期望空字符终止字符串,它也不起作用。从上面的代码片段中可以明显看出,但它也在JLS(10.9.字符数组不是字符串):

在 Java 编程语言中,与 C 不同,数组的数组不是 ,并且 a 和 的数组都不会以“\u0000”(NUL 字符)终止。charStringStringchar


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

现在我们谈论的是一个完全不同的东西,即字符串如何在屏幕上呈现。事实是,如果你使用丁蝙蝠字体,即使是“Hello world!”也会看起来很时髦。Unicode 字符串在一个区域设置中可能看起来很时髦,但在另一个区域设置中却不然。即使是一个正确呈现的包含中文字符的unicode字符串,对于来自格陵兰岛的人来说,可能仍然看起来很时髦。

也就是说,无论如何,空字符可能看起来都很时髦;通常它不是您要显示的字符。也就是说,由于空字符不是字符串终止符,因此Java完全能够以这种或那种方式处理它。


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

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

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


答案 2

可能应更改为

firstName = firstName.trim().replaceAll("\\.", "");