我已经看到使用String.replaceAll("","");
作为从Java中的字符串中消除“空白”或“非打印字符”的一些方法的参考。这是错误的,因为答案将证明。
value = value.replaceAll("", "");
答案 0 :(得分:0)
使用Junit,我测试每个Unicode字符,从\ u0000到\ uffff。
@Test
public void testReplaceBlanks(){
char input = 0;
char escape = '\u0000';
for(char i = 0; i <= 65535; ++i){
input = (char) (escape + i);
System.out.print(input);
System.out.print(" ");
if( i % 80 == 0){
System.out.println();
}
String test = new String(Character.toString(input));
assertTrue(!"".equals(test.replaceAll("", "")));
if(i == 65535)
break;
}
}
我没有找到一行代码,其中代码行有用。
由于我在互联网上发现了这个问题几次,这是一个更强大的测试用例:
这里的主要问题是,这行代码是NO-OP。
value = value.replaceAll(“”,“”);
考虑以下测试用例:
public static void println(String s) {
System.out.println(s);
}
@Test
public void testNullStripWithEmptyString() {
String input = "foo" + '\0';
String input2 = "foo";
println(input);
println("input:");
printBytes(input.getBytes());
println("input2:");
printBytes(input2.getBytes());
String testValue = input.replaceAll("", "");
println("testValue:");
printBytes(testValue.getBytes());
String testvalue2 = input2.replaceAll("","");
println("testvalue2");
printBytes(testvalue2.getBytes());
assertFalse(input.equals(input2));
assertFalse(testValue.equals(testvalue2));
}
此测试用例首先演示了在两个输入字符串的字节表示中,空字节出现在第一个字节中,而不出现在第二个字节表示中。然后我们继续调用* .replaceAll(“”,“”);并将值存储到两个新变量testValue和testvalue2中。
然后导致第一个断言,断言两个值不应该等于调用普通的String equals方法。这是非常正确的,因为我们在字符串后面附加了一个非打印空字节。然而,棺材中的钉子在证明在调用* .replaceAll(“”,“”)之后这种情况仍然存在;在两个testValue字符串上。
防止非打印或NULL字节的唯一方法是实现以下测试用例:
@Test
public void testNullStripWithNullUnicodeEscape(){
String input = "foo" + '\0';
String input2 = "foo";
println(input);
println("input:");
printBytes(input.getBytes());
println("input2:");
printBytes(input2.getBytes());
String testValue = input.replaceAll("\u0000", "");
println("testValue:");
printBytes(testValue.getBytes());
String testvalue2 = input2.replaceAll("\u0000","");
println("testvalue2");
printBytes(testvalue2.getBytes());
assertFalse(input.equals(input2));
assertTrue(testValue.equals(testvalue2));
}