2 Stimmen

Java Regex Ersetzen mit Erfassungsgruppe

Mögliches Duplikat:
Java Regex Ersetzen mit Erfassungsgruppe

Gibt es eine Möglichkeit, eine Regexp durch den geänderten Inhalt einer Erfassungsgruppe zu ersetzen?

Exemple :

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

Und ich möchte alle Vorkommnisse durch $1 multipliziert mit 3 ersetzen.

bearbeiten:

Sieht so aus, als wäre etwas nicht in Ordnung :(

Wenn ich die

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

Es wird eine IllegalStateException ausgelöst: Keine Übereinstimmung gefunden

Aber

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

funktioniert gut, aber ich kann die $1 nicht ändern :(

edit2:

Jetzt klappt es :)

17voto

Alan Moore Punkte 70949

Die endgültige Lösung für dieses Problem wurde von Elliott Hughes in seinem Blog vor ein paar Jahren. Elliott führt in der Online-Version immer wieder sinnlose Abhängigkeiten zu anderen Klassen ein, daher werde ich hier eine eigenständige Version veröffentlichen (die Abhängigkeiten sind nur in den Tests in der main() Methode).

import java.util.regex.*;

/**
 * A Rewriter does a global substitution in the strings passed to its
 * 'rewrite' method. It uses the pattern supplied to its constructor, and is
 * like 'String.replaceAll' except for the fact that its replacement strings
 * are generated by invoking a method you write, rather than from another
 * string. This class is supposed to be equivalent to Ruby's 'gsub' when
 * given a block. This is the nicest syntax I've managed to come up with in
 * Java so far. It's not too bad, and might actually be preferable if you
 * want to do the same rewriting to a number of strings in the same method
 * or class. See the example 'main' for a sample of how to use this class.
 *
 * @author Elliott Hughes
 */
public abstract class Rewriter
{
  private Pattern pattern;
  private Matcher matcher;

  /**
   * Constructs a rewriter using the given regular expression; the syntax is
   * the same as for 'Pattern.compile'.
   */
  public Rewriter(String regex)
  {
    this.pattern = Pattern.compile(regex);
  }

  /**
   * Returns the input subsequence captured by the given group during the
   * previous match operation.
   */
  public String group(int i)
  {
    return matcher.group(i);
  }

  /**
   * Overridden to compute a replacement for each match. Use the method
   * 'group' to access the captured groups.
   */
  public abstract String replacement();

  /**
   * Returns the result of rewriting 'original' by invoking the method
   * 'replacement' for each match of the regular expression supplied to the
   * constructor.
   */
  public String rewrite(CharSequence original)
  {
    this.matcher = pattern.matcher(original);
    StringBuffer result = new StringBuffer(original.length());
    while (matcher.find())
    {
      matcher.appendReplacement(result, "");
      result.append(replacement());
    }
    matcher.appendTail(result);
    return result.toString();
  }

  public static void main(String... args) throws Exception
  {
    String str = "12 54 1 65";

    // anonymous subclass
    Rewriter tripler = new Rewriter("(\\d{1,2})")
    {
      public String replacement()
      {
        int intValue = Integer.valueOf(group(1));
        return String.valueOf(intValue * 3);
      }
    };
    System.out.println(tripler.rewrite(str));

    // inline subclass
    System.out.println(new Rewriter("(\\d{1,2})")
    {
      public String replacement()
      {
        int intValue = Integer.valueOf(group(1));
        return String.valueOf(intValue * 3);
      }
    }.rewrite(str));

  }
}

0voto

Bart Kiers Punkte 160101

Nein, das kann man mit Regex nicht machen. Regex hat keine Vorstellung von numerischen Werten, daher ist das Rechnen mit Zahlen nicht möglich (angenommen, Sie wollten "12 54 1 65" in "36 162 3 195" umwandeln).

Beachten Sie, dass mit einigen Sprachen und Regex-Implementierungen können Sie dies tun (Perl, wie Chris gepostet), aber dies ist nicht eine Regex Sache, und vor allem nicht eine Java-Regex Sache. Sie sagten, dass Sie das Problem bereits gelöst haben, also nehme ich an, dass Sie den "manuellen" Weg gegangen sind, indem Sie jede Übereinstimmung in eine ganze Zahl umgewandelt und diese mit 3 multipliziert haben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X