Est-il possible de remplacer une expression rationnelle par le contenu modifié du 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 toutes les occurrences par 1 $ multiplié par 3.
edit:
On dirait que quelque chose 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 lève une exception IllegalStateException: Aucune correspondance trouvée.
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 bien, mais je ne peux pas changer le $ 1 :(
edit:
Maintenant, ça marche :)
Que diriez-vous:
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 à cette première correspondance et remplacer toutes les correspondances par la première valeur de la maches multipliée par 3.
Et si vous souhaitez remplacer chaque correspondance par la valeur de cette correspondance multipliée 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 la documentation de Matcher
, où tout cela et beaucoup d’autres sont couverts en détail.
la réponse de Earl vous donne la solution, mais je pensais que j'ajouterais quel est le problème qui cause votre IllegalStateException
. Vous appelez group(1)
sans avoir au préalable appelé une opération correspondante (telle que find()
). Cela n'est pas nécessaire si vous utilisez simplement $1
Car la replaceAll()
est l'opération correspondante.
Java 9 offre une Matcher.replaceAll()
qui accepte une fonction de remplacement:
resultString = regexMatcher.replaceAll(
m -> String.valueOf(Integer.parseInt(m.group()) * 3));
Source: Java-implémentation-de-rubys-gsub
Usage:
// 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 (repensée):
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();
}
}