posts - 8,  comments - 6,  trackbacks - 0

          2.5  使用正則表達(dá)式進(jìn)行替換

          在上一節(jié)中,介紹了用于匹配一個(gè)String中的模式和用于從一個(gè)子模式組中檢索數(shù)據(jù)的正則表達(dá)式。使用regex,還可以用新的值替代匹配的模式。完成此操作的一種方法是使用Matcher類的replaceAll方法,它將返回一個(gè)字符串,將所有匹配的子串替換為給定的字符串。為了說(shuō)明此方法,查找一個(gè)文件內(nèi)出現(xiàn)的所有repetition單詞并使用單詞duplication來(lái)替換它們:
          String data = getStringData();
          Pattern repPattern = Pattern.compile("(\\s)(repetition)([\\s;\\.,])");
          Matcher repMatcher = repPattern.matcher(data);
          String newData = repMatcher.replaceAll("$1duplication$3");

          為了查找單詞,需要捕獲它前后的空白(或標(biāo)點(diǎn)符號(hào))。需要注意的是,如果此單詞出現(xiàn)在data字符串的開頭,那么上述的代碼不會(huì)匹配它,因?yàn)橐鸭俣ㄋ那昂蟠嬖诳瞻追3藛卧~repetition被替換外,我們希望文本中的其他內(nèi)容與原始文本保持一致,包括單詞周圍的空白字符。這里的美元符號(hào)($)顯然不表示貨幣。它表示對(duì)從regex模式中捕獲的組1和組3的逆向引用,包含最初匹配的空白或標(biāo)點(diǎn)符號(hào)。這樣,與它們對(duì)應(yīng)的值將插入到替換文本中。

          String類(在JDK 1.4或更高的版本中)有一個(gè)replaceAll方法,其工作機(jī)制類似于Matcher中的replaceAll方法。這使得它可以很方便地替換一個(gè)與模式匹配的子串:

          String data = getStringData();
          String result =
          data.replaceAll("(\\s)(repetition)([\\s;\\.,])", "$1duplication$3");

          replaceAll方法返回一個(gè)新的字符串,其中所有匹配的部分已被新值替換。但是,使用Matcher仍有很多優(yōu)點(diǎn),因?yàn)橄鄬?duì)于字符串它有更大的靈活性。

          可以使用Matcher的find循環(huán)用新值依次替換每個(gè)匹配的部分。這樣使你能夠更好地控制替換過(guò)程。比如,可以在每次匹配的過(guò)程中應(yīng)用其他邏輯,甚至每次可以替換不同的值。這就用到了StringBuffer,StringBuffer用于保存更新的文本,并且一旦調(diào)用appendReplacement方法,Matcher就追加更新后的文本到緩存中。在處理每個(gè)匹配并執(zhí)行替換后,需要使用appendTail方法將最后一次匹配后的剩余字符串放置在輸出緩存中。圖2-1說(shuō)明了子串匹配和這兩種方法之間的關(guān)系。

          圖2-1  Matcher類的append方法 
          Matcher有一個(gè)相應(yīng)的append指針。指針最初從零開始,隨著每次調(diào)用appendReplacement向前移動(dòng)。這種設(shè)計(jì)是為了在一個(gè)find循環(huán)內(nèi)使用它。每次匹配后,調(diào)用appendReplacement方法,Matcher將指針?biāo)诘纳弦粋€(gè)位置到匹配之前指針?biāo)诘奈恢弥g的內(nèi)容,即未更改的文本合并到StringBuffer中。然后,Matcher替換當(dāng)前匹配的文本并將替換后的內(nèi)容放置在StringBuffer中。接下來(lái),Matcher將append指針移動(dòng)到當(dāng)前匹配結(jié)尾之后的第一個(gè)字符,然后重復(fù)此過(guò)程直到不再產(chǎn)生匹配。在找到所有匹配之后很可能剩下一個(gè)未匹配的部分。為了將這部分文本添加到輸出StringBuffer中,使用appendTail方法。
          現(xiàn)在使用這些方法將前面的替換例子重寫為一個(gè)循環(huán)。但是這一次對(duì)于每個(gè)匹配,將使用一個(gè)隨機(jī)選擇的同義詞(repetition、duplication、copying、reiteration、recurrence或redundancy)來(lái)替代單詞repetition:
          StringBuffer result = new StringBuffer();
          String[] wordChoices = new String[]
          {"repetition", "duplication", "copying",
          "reiteration", "recurrence", "redundancy"};
          Random rand = new Random();
          String data = getStringData();
          Pattern repPattern = Pattern.compile("(\\s)(repetition)([\\s;\\.,])");
          Matcher repMatcher = repPattern.matcher(data);
          while (repMatcher.find()) {
          // pick a word at random
          int wordIndex = rand.nextInt(wordChoices.length);
          String replacement = "$1" + wordChoices[wordIndex] + "$3";
          repMatcher.appendReplacement(result, replacement);
          }
          repMatcher.appendTail(result);
          System.out.println(result);

          可以按需求改寫find循環(huán)中的邏輯來(lái)對(duì)每個(gè)匹配進(jìn)行所需的處理。此外,還可以使用前面討論過(guò)的Matcher的方法:group、start和end。可以使用這些技術(shù)的組合有選擇地修改或刪除一個(gè)文件中每部分匹配的文本。

          <2025年8月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          主站蜘蛛池模板: 哈巴河县| 凉城县| 喀喇沁旗| 成武县| 洞头县| 吴川市| 铁力市| 广元市| 湖口县| 大理市| 宝山区| 三明市| 恩施市| 阿克苏市| 湖口县| 洪湖市| 惠安县| 上犹县| 翁牛特旗| 阿克苏市| 大关县| 常德市| 法库县| 闻喜县| 铜川市| 英山县| 集贤县| 荥经县| 大城县| 麻城市| 斗六市| 巢湖市| 灌阳县| 乌苏市| 闽清县| 济宁市| 乡城县| 金阳县| 黄平县| 七台河市| 阿尔山市|