2010-03-26 129 views
29

測試了某人的代碼,我注意到有幾個JSP頁面打印出怪異的非ASCII字符。進入源代碼我發現這個珍聞:Java字符串替換和NUL(NULL,ASCII 0)字符?

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

用空字符替換字符中的字符甚至在Java中工作嗎?我知道會終止一個C字符串。這是否會成爲時髦人物的罪魁禍首?

+1

「我注意到有幾個JSP頁面打印時髦的非ASCII字符。」:這個問題的根本原因完全在於別處。谷歌「mojibake」。 – BalusC 2010-03-26 12:52:53

回答

78

用空字符替換字符中的字符甚至在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. An Array of Characters is Not a String):

在Java編程語言,不同於C,的char陣列不是String,並且既不是String也不陣列的char以'\ u0000'(NUL字符)結尾。


這會是罪魁禍首的時髦人物?

現在我們談論的是完全不同的東西,即字符串如何在屏幕上呈現。事實是,即使「你好世界!」如果你使用dingbats字體會看起來很時髦。 unicode字符串在一個語言環境中可能看起來很時髦,但在另一個語言環境中可能看起來很時髦即使是一個正確渲染的包含中文字符的unicode字符串,對於來自格陵蘭島的某些人來說仍然會顯得很怪異。

也就是說,空字符可能看起來很時髦;通常它不是你想要顯示的角色。也就是說,由於null字符不是字符串終止符,因此Java不僅能以這種或那種方式處理它。


我們解決我們假設有什麼預期效果,即刪除字符串中的所有時段,最簡單的辦法就是使用replace(CharSequence, CharSequence)超載。

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

replaceAll解決方案在這裏提到過,但與正則表達式,這就是爲什麼你需要躲避點元字符,而且很可能要慢一些工作。

+2

現在,這是一個很好的解釋。而且你正在用正確的方法來替換這些東西:) – BalusC 2010-03-26 13:50:57

+1

+1:非常好,非常徹底! – 2010-03-26 15:49:41

4

用空字符替換字符串中的字符 即使在 Java中?

這會是罪魁禍首的時髦人物?

很可能。

4

我認爲應該是這樣。要清除角色,您應該使用replace(".", "")

+3

這是一個語法錯誤。 – 2010-03-26 12:55:47

+0

糟糕,沒有測試它。我現在要糾正它。 – 2010-03-26 14:21:53

8

應該可能改爲

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

我實際上是要用它來修復它。 – praspa 2010-03-26 12:54:50

+6

'replaceAll'就像這裏的大錘。你只想用空字符串替換char。你根本不想替換模式。只需使用'replace(「。」,「」)'。 – BalusC 2010-03-26 12:57:20

1

這確實會導致 「時髦人物」:

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

生產:

Mr[] Foo 
在我的Eclipse控制檯,其中[]是

顯示爲方框。正如其他人發佈的那樣,使用String.replace()