有這樣一個簡單需求:寫一個方法,實現從原始字符串中刪除與之匹配的所有子字符串,比如在“藍藍的天,白雲飄”中,刪除“白雲飄”,輸出“藍藍的天,”,代碼如下:
package deep;
public class StringUtils {
// 刪除字符串
public static String remove(String source, String sub) {
return source.replaceAll(sub, "");
}
}
StringUtils工具類很簡單,它採用了String的replace方法,該方法是做字符串替換的,我們來編寫一個測試用例,檢查remove方法是否正確,如下所示:
package deep;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class StringTest {
@Test
public void test() {
assertTrue(StringUtils.remove("好是好", "好").equals("是"));
}
}
測試的結果是綠條(Green Bar),正確無誤,但是再看看如下的測試用例:
package deep;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class StringTest {
@Test
public void test() {
assertTrue(StringUtils.remove("$是$", "$").equals("是"));
}
}
上面只是把“好是好”中的兩個“好”字替換成了一個“$”符號,猜猜結果會是什麼,應該也是綠條吧?但是非常遺憾,結果是紅條,測試未通過。就這麼簡單一個替換,爲什麼測試通不過呢?
問題就出在了replaceAll方法上,注意:它要求的第一個參數是一個正則表達式,符合正則表達式的字符串纔會被替換。對上面的例子來說,第一個測試案例傳遞進來的是一個字符串“好”,這是一個全匹配查找替換,處理得非常正確,第二個測試案例傳遞進來的是“$”符號,“$”符號在正則表達式中表示的是字符串的結束位置,也就是說執行完replaceAll後,在字符串結尾的地方加上了空字符串,其結果還是“$是$”,所以測試失敗也就在所難免了。問題清楚了,解決方案也就出來了:使用replace方法替代即可,它是reolaceAll方法的簡化版,可傳遞兩個String參數繼續替換,與我們的編碼意圖是相吻合的。