從 Java 中的字符串中刪除標點符號
一、概述
從字符串中刪除標點符號是文本處理和分析中的常見做法。
在本快速教程中,讓我們探索如何輕鬆地從給定字符串中刪除標點符號。
二、問題簡介
假設我們有一個字符串:
static final String INPUT = "It's 1 W ord ([email protected]#$%^&*{}[];':\")<>,.";
正如我們所見,字符串INPUT
包含數字、字母、空格和各種標點符號。
我們的目標是僅從字符串中刪除標點符號,並在結果中保留字母、數字和空格:
static final String EXPECTED = "Its 1 W ord ";
在本教程中,我們將主要使用 Java 標準庫附帶的String.replaceAll()
方法來解決問題。
為簡單起見,我們將使用單元測試斷言來驗證結果是否符合預期。
那麼接下來,讓我們看看標點符號是如何被刪除的。
3. 使用正則表達式“ [^\sa-zA-Z0-9]
”和“ \p{Punct}
”
我們提到過使用String.replaceAll()
方法從輸入字符串中刪除標點符號。 replaceAll()
方法執行基於正則表達式的字符串替換。它檢查輸入字符串並用替換字符串替換所有與我們的正則表達式模式匹配的部分。
因此,正則表達式模式是解決這個問題的關鍵。
因為我們想在結果中保留字母、數字和空格,所以我們可以用空字符串替換任何不是數字、字母或空格字符的字符。我們可以將這些字母與正則表達式的字符範圍[^\sa-zA-Z0-9]
匹配。
接下來,讓我們創建一個測試來檢查它是否有效:
String result = INPUT.replaceAll("[^\\sa-zA-Z0-9]", "");
assertEquals(EXPECTED, result);
如果我們執行它,測試就會通過。正則表達式模式非常簡單。對於那些不熟悉語法的人,注意以下幾點可能會有所幫助:
-
[^…] –
不是[…].
例如,[^0-9]
匹配任何非數字。 -
\s
– \s 匹配任何空白字符,例如空格和 TAB。
此外,Java 的正則表達式引擎支持 POSIX 字符類。因此,我們可以直接使用\\p{Punct}
字符類來匹配**!”#$%&'()*+,-./:;<=>[email protected][\]^_`{|}~:**
String result = INPUT.replaceAll("\\p{Punct}", "");
assertEquals(EXPECTED, result);
當我們運行上面的測試時,它也通過了。
4. 當輸入是 Unicode 字符串時
我們已經看到了兩種成功地從輸入字符串中刪除標點符號的方法。如果我們仔細查看INPUT
字符串,就會發現它由 ASCII 字符組成。
可能會出現一個問題——如果我們收到這樣的字符串,解決方案是否仍然有效:
static final String UNICODE_INPUT = "3 March März 三月 březen маршировать ([email protected]#$%^&*{}[];':\")<>,.";
除了數字“ 3
”、空白字符和標點符號外,此輸入還包括英語、德語、中文、捷克語和俄語的單詞“ March
”。因此,與前面的INPUT
字符串不同, UNICODE_INPUT
變量包含 Unicode 字符。
刪除標點符號後,預期結果應如下所示:
static final String UNICODE_EXPECTED = "3 March März 三月 březen маршировать ";
那麼接下來,讓我們測試一下我們的兩個解決方案是否仍然適用於此輸入:
String result1 = UNICODE_INPUT.replaceAll("[^\\sa-zA-Z0-9]", "");
assertNotEquals(UNICODE_EXPECTED, result1);
上面的測試通過。但我們應該注意斷言是assertNotEquals()
。因此,“刪除[^\sa-zA-Z0-9]
” 方法不會產生預期的結果。讓我們看看它實際產生了什麼結果:
String actualResult1 = "3 March Mrz bezen ";
assertEquals(actualResult1, result1);
因此,所有非 ASCII 字符都與標點符號一起被刪除。顯然, “刪除[^\sa-zA-Z0-9]
” 方法不適用於 Unicode 字符串。
但是我們可以通過將“ a-zA-Z
”範圍替換為“ \p{L}
”來修復它:
String result3 = UNICODE_INPUT.replaceAll("[^\\s\\p{L}0-9]", "");
assertEquals(UNICODE_EXPECTED, result3);
值得一提的是**\p{L}
匹配任何字母,包括 Unicode 字符。**
另一方面, “刪除\p{Punct}
”方法仍然適用於 Unicode 輸入:
String result2 = UNICODE_INPUT.replaceAll("\\p{Punct}", "");
assertEquals(UNICODE_EXPECTED, result2);
這是因為\\p{Punct}
只匹配標點字符。
5.結論
在本文中,我們學習瞭如何使用標準的String.replaceAll()
方法從字符串中刪除標點符號:
-
String.replaceAll(“[^\\sa-zA-Z0-9]”, “”)
– 僅適用於帶有 ASCII 字符的輸入字符串 -
String.replaceAll(“\\p{Punct}”, “”)
– 適用於 ASCII 和 Unicode 字符串 -
String.replaceAll(“[^\\s\\p{L}0-9]”, “”)
– 適用於 ASCII 和 Unicode 字符串
與往常一樣,此處提供的所有代碼片段都可以在 GitHub 上找到。