2009-08-14 41 views
63

有什麼方法可以用修改後的捕獲組內容替換正則表達式嗎?Java正則表達式替換爲捕獲組

例子:

Pattern regex = Pattern.compile("(\\d{1,2})"); 
Matcher regexMatcher = regex.matcher(text); 
resultString = regexMatcher.replaceAll("$1"); // *3 ?? 

而且我想和乘以$ 1替換所有發生3

編輯:

的樣子,什麼是錯的:(

如果我使用

Pattern regex = Pattern.compile("(\\d{1,2})"); 
Matcher regexMatcher = regex.matcher("12 54 1 65"); 
try { 
    String resultString = regexMatcher.replaceAll(regexMatcher.group(1)); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

它拋出IllegalStateException:沒有找到匹配

Pattern regex = Pattern.compile("(\\d{1,2})"); 
Matcher regexMatcher = regex.matcher("12 54 1 65"); 
try { 
    String resultString = regexMatcher.replaceAll("$1"); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

工作正常,但我不能改變的$ 1 :(

編輯:

現在,它的工作:)

+0

通過直接在一根繩子上的合作,我們終於等來了[這裏](HTTP://計算器.com/a/6057820/1422630) – 2015-12-11 20:30:03

回答

73

如何:

if (regexMatcher.find()) { 
    resultString = regexMatcher.replaceAll(
      String.valueOf(3 * Integer.parseInt(regexMatcher.group(1)))); 
} 

要獲得第一個匹配項,請使用#find()。在這之後,你可以使用#group(1)第一maches值乘以3

而如果是指這第一場比賽,並更換所有比賽,你想那場比賽的價值乘以3,以取代每場比賽:

Pattern p = Pattern.compile("(\\d{1,2})"); 
    Matcher m = p.matcher("12 54 1 65"); 
    StringBuffer s = new StringBuffer(); 
    while (m.find()) 
     m.appendReplacement(s, String.valueOf(3 * Integer.parseInt(m.group(1)))); 
    System.out.println(s.toString()); 

你可能想看看Matcher's documentation,在這裏和更多的東西詳細介紹。

+5

是的,但你失去了原來的字符串。如果它是「一個1 2 3」,你將不會有一個 – 2011-04-13 14:55:20

+18

這非常有幫助!另外一個補充是,如果你的匹配文本和你的匹配不在最後,你需要調用m.appendTail(s); – mezzie 2011-07-13 16:23:51

+0

查找帶有靜態文本的組時,請小心,如Pattern.compile(「var myVar = \」(。*)\「;」); - 它將取代所有發現的不僅是小組。請參閱John O. – 2014-04-18 13:06:06

10

伯爵的回答給你的解決方案,但我想我會添加什麼問題導致你的IllegalStateException。您在沒有先調用匹配操作(例如find())的情況下調用group(1)。如果您剛剛使用$1,則不需要此操作,因爲replaceAll()是匹配操作。

1

來源:java-implementation-of-rubys-gsub

用法:

// Rewrite an ancient unit of length in SI units. 
String result = new Rewriter("([0-9]+(\\.[0-9]+)?)[- ]?(inch(es)?)") { 
    public String replacement() { 
     float inches = Float.parseFloat(group(1)); 
     return Float.toString(2.54f * inches) + " cm"; 
    } 
}.rewrite("a 17 inch display"); 
System.out.println(result); 

// The "Searching and Replacing with Non-Constant Values Using a 
// Regular Expression" example from the Java Almanac. 
result = new Rewriter("([a-zA-Z]+[0-9]+)") { 
    public String replacement() { 
     return group(1).toUpperCase(); 
    } 
}.rewrite("ab12 cd efg34"); 
System.out.println(result); 

實施(重新設計):

import static java.lang.String.format; 

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public abstract class Rewriter { 
    private Pattern pattern; 
    private Matcher matcher; 

    public Rewriter(String regularExpression) { 
     this.pattern = Pattern.compile(regularExpression); 
    } 

    public String group(int i) { 
     return matcher.group(i); 
    } 

    public abstract String replacement() throws Exception; 

    public String rewrite(CharSequence original) { 
     return rewrite(original, new StringBuffer(original.length())).toString(); 
    } 

    public StringBuffer rewrite(CharSequence original, StringBuffer destination) { 
     try { 
      this.matcher = pattern.matcher(original); 
      while (matcher.find()) { 
       matcher.appendReplacement(destination, ""); 
       destination.append(replacement()); 
      } 
      matcher.appendTail(destination); 
      return destination; 
     } catch (Exception e) { 
      throw new RuntimeException("Cannot rewrite " + toString(), e); 
     } 
    } 

    @Override 
    public String toString() { 
     StringBuilder sb = new StringBuilder(); 
     sb.append(pattern.pattern()); 
     for (int i = 0; i <= matcher.groupCount(); i++) 
      sb.append(format("\n\t(%s) - %s", i, group(i))); 
     return sb.toString(); 
    } 
}