2 Stimmen

Wie implementiert man "supplant" in Java?

"supplant() führt eine Variablenersetzung an der Zeichenkette durch. Sie durchsucht die Zeichenkette nach Ausdrücken, die in geschweifte Klammern { } eingeschlossen sind. Wenn ein Ausdruck gefunden wird, wird er als Schlüssel für das Objekt verwendet, und wenn der Schlüssel einen String- oder Zahlenwert hat, wird er durch den Klammerausdruck ersetzt und der Vorgang wiederholt."

Genauer gesagt, ich versuche, etwas zu tun wie:

public static String supplant(CharSequence message, Map<String,Object> params)

Ich versuche, eine Regex wie \{([ \w ]*)\}, um die Variablen zu erfassen und dann die Map nachzuschlagen und zu ersetzen, aber ich konnte keinen Regex schreiben, der passt...

Wie würden Sie supplant() in Java implementieren?

2voto

Mike Daniels Punkte 8472

Muss es mit genau diesem Format funktionieren? Java verfügt bereits über eingebaute Methoden zur Ersetzung von Variablen in Zeichenketten.

Siehe:

1voto

Alan Moore Punkte 70949

Was Sie beschreiben, wird üblicherweise als Vorlagenerstellung . Es gibt viele Templating-Anwendungen und -Bibliotheken, aber wenn Sie nur eine schnelle und unkomplizierte Lösung wollen, kann sie leicht mit Regexen implementiert werden.

In vielen Regex-Varianten würden Sie eine eingebaute Rückruf o Aufforderung Mechanismus, wie der von PHP preg_replace_callback Funktion oder Perl's /e y /ee Modifikatoren. Java hat so etwas nicht, aber es bietet eine API, mit der Sie es selbst implementieren können. Hier ist ein Beispiel:

import java.util.*;
import java.util.regex.*;

public class Test
{
  public static void main(String[] args) throws Exception
  {
    String s = "Lorem ipsum {foo} impedit civibus ei pri, legimus\n" +
        "antiopam no {marco}, quo id everti forensibus maiestatis.";
    Map<String,Object> p = new HashMap<String,Object>()
    {{
      put("foo", "BAR");
      put("marco", "POLO!");
    }};
    System.out.printf("%s%n%n%s%n", s, supplant(s, p));
  }

  public static CharSequence supplant(CharSequence message, Map<String,Object> params)
  {
    Matcher m = Pattern.compile("\\{(\\w+)\\}").matcher(message);
    StringBuffer sb = new StringBuffer();
    while (m.find())
    {
      m.appendReplacement(sb, "");
      String key = m.group(1);
      sb.append(params.get(key).toString());
    }
    m.appendTail(sb);
    return sb.toString();
  }
}

Natürlich lässt dieser Code einige wesentliche Komponenten aus (vor allem die Behandlung von Ausnahmen), aber er demonstriert die wichtigsten Punkte dieser Technik:

  1. Erfassen Sie den Inhalt innerhalb der geschweiften Klammern mit Hilfe von Klammern, und greifen Sie dann auf ihn zu, indem Sie group(1) auf den Matcher.
  2. Verwenden Sie appendReplacement(sb, "") um den Text anzuhängen, der zwischen der vorherigen Übereinstimmung (falls es eine gab) und der aktuellen Übereinstimmung erschien.
  3. Suchen Sie die Ersetzung und fügen Sie sie mit StringBuffer's append() Methode. (Sie könnte kombinieren Sie die Schritte 2 und 3, indem Sie die Ersetzungszeichenfolge als zweites Argument an appendReplacement() aber dann müssten Sie auf Dollarzeichen und Backslashes in der Zeichenkette achten, die eine Sonderbehandlung erfahren. Dieser Weg ist viel einfacher.)
  4. Verwenden Sie appendTail(sb) um das anzuhängen, was nach der letzten Übereinstimmung übrig ist.

Mehrere Leute haben Hilfsklassen veröffentlicht, mit denen Sie diese Art von Aufgabe erledigen können, ohne den ganzen Boilerplate-Code schreiben zu müssen. Mein Favorit ist Elliott Hughes' Rewriter .

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