2009-08-14 7 views
63

Existe-t-il un moyen de remplacer une expression rationnelle par le contenu modifié du groupe de capture?Java Regex Remplacer par le groupe de capture

Exemple:

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

Et je voudrais remplacer tout événement avec 1 $ multiplié par 3.

modifier:

On dirait, quelque chose qui ne va pas :(

Si j'utilise

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(); 
} 

Il lance une IllegalStateException: Aucun résultat trouvé

Mais

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(); 
} 

fonctionne très bien, mais je ne peux pas changer le 1 :(

$ modifier:

maintenant , ça marche :)

+0

en travaillant directement sur une chaîne, nous avons enfin [ce] (http: // stackoverflow .com/a/6057820/1422630) –

Répondre

73

Que diriez-vous de:

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

Pour obtenir la première correspondance, utilisez #find(). Après cela, vous pouvez utiliser #group(1) pour faire référence à ce premier match, et remplacer tous les matches de la première valeur de MACHES multipliée par 3.

Et si vous voulez remplacer chaque match avec la valeur de ce match multiplié par 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()); 

Vous voudrez peut-être regarder à travers Matcher's documentation, où ceci et beaucoup d'autres choses sont couvertes en détail.

+5

oui mais vous perdez la chaîne d'origine. si c'est "un 1 2 3" vous n'aurez pas le –

+18

Cela a été plutôt utile! Un ajout est que si votre correspondant à un texte et vos correspondances ne sont pas à la fin, vous devez appeler m.appendTail (s); – mezzie

+0

Soyez prudent lorsque vous trouvez des groupes avec du texte statique comme Pattern.compile ("var myVar = \" (. *) \ ";"); - Il va remplacer tous trouvés non seulement le groupe.voir aussi le lien de John O. –

10

La réponse de earl vous donne la solution, mais je voudrais ajouter le problème qui est à l'origine de votre IllegalStateException. Vous appelez group(1) sans avoir préalablement appelé une opération de correspondance (par exemple find()). Ce n'est pas nécessaire si vous utilisez simplement $1 puisque l'opération replaceAll() est l'opération correspondante.

1

Source: java-implementation-of-rubys-gsub

Utilisation:

// 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); 

mise en œuvre (remodelé):

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(); 
    } 
}