在 Java 中尋找最後一個模式之後的子字串
1. 概述
在 Java 中,有很多情況我們需要提取給定String
中最後一次出現特定模式之後出現的子字串。這在處理文件路徑、URL 或任何結構化文字時特別有用。
在這個快速教程中,我們將探索實現這一目標的各種方法。
2.問題介紹
例如,假設我們有以下String:
static final String INPUT1 = "a, b, c, I need this value";
給定“, ”
(一個逗號後面跟著三個空格)作為模式,我們希望找到緊接在該模式最後一次出現之後出現的子字串:
static final String EXPECTED1 = "I need this value";
當然,也有一些邊緣情況。例如,如果輸入String
根本不包含模式,或者模式最後一次出現後沒有任何內容,我們希望結果為空String
:
static final String INPUT2 = "no-pattern-found";
static final String EXPECTED2 = "";
static final String INPUT3 = "a, b, c, ";
static final String EXPECTED3 = "";
接下來,讓我們來探討解決這個問題的不同方法。
3. 使用String.lastIndexOf()
如果我們可以在輸入String
中找到模式的最後一個索引,我們可以使用substring()
來擷取結果:
inputString.substring(lastIndexOfThePattern + pattern.length())
String.lastIndexOf()
方法傳回最後一次出現的模式。如果輸入不包含模式,則傳回 -1 。因此,讓我們創建一個方法來提取所需的文字並轉換不同的場景:
String afterTheLastPatternBySubstring(String input, String pattern) {
int index = input.lastIndexOf(pattern);
return index >= 0 ? input.substring(index + pattern.length()) : "";
}
接下來,讓我們驗證該方法是否按預期工作:
String pattern = ", ";
String result1 = afterTheLastPatternBySubstring(INPUT1, pattern);
assertEquals(EXPECTED1, result1);
String result2 = afterTheLastPatternBySubstring(INPUT2, pattern);
assertEquals(EXPECTED2, result2);
String result3 = afterTheLastPatternBySubstring(INPUT3, pattern);
assertEquals(EXPECTED3, result3);
測試通過。但是, lastIndexOf()
僅支援文字文字模式。接下來,讓我們來看看支援正規表示式模式的其他方法。
4. 使用String.split()
或者,我們可以使用String.split()
透過使用正規表示式模式作為分隔符號來取得String
陣列。然後,最後一個陣列元素將是結果。我們將使用正規表示式“, {3}”
作為模式。
當然,這只是基本想法。我們需要考慮一些調整以涵蓋所有邊緣情況。
例如,當我們split()
輸入時,我們應該使用負limit
參數。這是因為預設限制 (0) 會丟棄所有尾隨的空String
。但負數限制則不然。一個例子說明了為什麼需要這樣做:
String pattern = ", {3}";
String[] array1 = INPUT3.split(pattern);
assertArrayEquals(new String[] { "a", "b", "c", }, array1);
String[] array2 = INPUT3.split(pattern, -1);
assertArrayEquals(new String[] { "a", "b", "c", "" }, array2);
另外,我們應該處理輸入不包含模式的情況。在這種情況下, split()
結果的length
<2
:
String afterTheLastPatternBySplit(String input, String pattern) {
String[] arr = input.split(pattern, -1);
return (arr.length >= 2)? arr[arr.length - 1] : "";
}
接下來我們來測試一下:
String pattern = ", {3}";
String result1 = afterTheLastPatternBySplit(INPUT1, pattern);
assertEquals(EXPECTED1, result1);
String result2 = afterTheLastPatternBySplit(INPUT2, pattern);
assertEquals(EXPECTED2, result2);
String result3 = afterTheLastPatternBySplit(INPUT3, pattern);
assertEquals(EXPECTED3, result3);
正如我們所看到的,這種方法為我們的三個輸入產生了預期結果。
5. 使用String.replaceAll()
我們可以從不同的角度來看這個問題:如果我們從輸入的開頭刪除直到最後一個模式出現,那麼剩下的文字就是我們想要的。在我們的範例中,正規表示式模式將為「 .*, {3}
」。
因此,我們可以利用String.replaceAll()
來解決這個問題:
String afterTheLastPatternByReplaceAll(String input, String pattern) {
String result = input.replaceAll(pattern, "");
return result.equals(input) ? "" : result;
}
在範例中,我們透過比較替換結果和輸入來確定輸入是否包含模式。
最後,讓我們來測試一下這個方法:
String pattern = ".*, {3}";
String result1 = afterTheLastPatternByReplaceAll(INPUT1, pattern);
assertEquals(EXPECTED1, result1);
String result2 = afterTheLastPatternByReplaceAll(INPUT2, pattern);
assertEquals(EXPECTED2, result2);
String result3 = afterTheLastPatternByReplaceAll(INPUT3, pattern);
assertEquals(EXPECTED3, result3);
事實證明, replaceAll()
方法可以完成這項工作。
六,結論
在本文中,我們探索了在特定模式最後一次出現後查找子字串的不同方法。透過理解和應用這些技術,我們可以有效地處理各種文字處理。
與往常一樣,範例的完整原始程式碼可在 GitHub 上取得。