0

我已经看到有关使用String.replaceAll("","");作为从 Java 中的字符串中消除“空白”或“非打印字符”的某种方法的参考。正如答案将证明的那样,这是错误的。

value = value.replaceAll("", "");

4

1 回答 1

0

使用 Junit,我测试了从 \u0000 到 \uffff 的每一个 Unicode 字符。

@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));
  }
于 2014-05-10T23:52:14.400 回答