2.5 使用正則表達式進行替換
在上一節中,介紹了用于匹配一個String中的模式和用于從一個子模式組中檢索數據的正則表達式。使用regex,還可以用新的值替代匹配的模式。完成此操作的一種方法是使用Matcher類的replaceAll方法,它將返回一個字符串,將所有匹配的子串替換為給定的字符串。為了說明此方法,查找一個文件內出現的所有repetition單詞并使用單詞duplication來替換它們:
String data = getStringData(); |
為了查找單詞,需要捕獲它前后的空白(或標點符號)。需要注意的是,如果此單詞出現在data字符串的開頭,那么上述的代碼不會匹配它,因為已假定它的前后存在空白符。除了單詞repetition被替換外,我們希望文本中的其他內容與原始文本保持一致,包括單詞周圍的空白字符。這里的美元符號($)顯然不表示貨幣。它表示對從regex模式中捕獲的組1和組3的逆向引用,包含最初匹配的空白或標點符號。這樣,與它們對應的值將插入到替換文本中。
String類(在JDK 1.4或更高的版本中)有一個replaceAll方法,其工作機制類似于Matcher中的replaceAll方法。這使得它可以很方便地替換一個與模式匹配的子串:
String data = getStringData(); |
replaceAll方法返回一個新的字符串,其中所有匹配的部分已被新值替換。但是,使用Matcher仍有很多優點,因為相對于字符串它有更大的靈活性。
可以使用Matcher的find循環用新值依次替換每個匹配的部分。這樣使你能夠更好地控制替換過程。比如,可以在每次匹配的過程中應用其他邏輯,甚至每次可以替換不同的值。這就用到了StringBuffer,StringBuffer用于保存更新的文本,并且一旦調用appendReplacement方法,Matcher就追加更新后的文本到緩存中。在處理每個匹配并執行替換后,需要使用appendTail方法將最后一次匹配后的剩余字符串放置在輸出緩存中。圖2-1說明了子串匹配和這兩種方法之間的關系。
![]() |
圖2-1 Matcher類的append方法 |
現在使用這些方法將前面的替換例子重寫為一個循環。但是這一次對于每個匹配,將使用一個隨機選擇的同義詞(repetition、duplication、copying、reiteration、recurrence或redundancy)來替代單詞repetition:
StringBuffer result = new StringBuffer(); |
可以按需求改寫find循環中的邏輯來對每個匹配進行所需的處理。此外,還可以使用前面討論過的Matcher的方法:group、start和end。可以使用這些技術的組合有選擇地修改或刪除一個文件中每部分匹配的文本。