it-swarm.com.de

Regex Named Groups in Java

Es ist mein Verständnis, dass die Java.regex package unterstützt keine benannten Gruppen ( http://www.regular-expressions.info/named.html ). Kann mich jemand auf eine Drittanbieter-Bibliothek verweisen, die dies tut?

Ich habe mir jregex angesehen, aber seine letzte Veröffentlichung war im Jahr 2002 und es hat bei mir unter Java5 nicht funktioniert (zugegebenermaßen habe ich es nur kurz versucht).

156
Dan

( Update : August 2011 )

Wie geofflane in seiner Antwort ​​erwähnt, unterstützt Java 7 jetzt benannte Gruppen .
tchrist ​​weist im Kommentar darauf hin, dass die Unterstützung begrenzt ist.
Er beschreibt die Einschränkungen in seiner großartigen Antwort " Java Regex Helper "

Java 7 regex mit dem Namen group support wurde bereits in September 2010 im Oracle-Blog vorgestellt.

In der offiziellen Version von Java 7 sind die Konstrukte zur Unterstützung der genannten Erfassungsgruppe:

  • (?<name>capturing text) Um eine benannte Gruppe "name" zu definieren
  • \k<name>, Um einen Rückverweis auf eine benannte Gruppe "name" zu erstellen
  • ${name} Verweist auf die erfasste Gruppe in Matchers Ersatzzeichenfolge
  • Matcher.group(String name) um die erfasste Eingabesubsequenz der angegebenen "benannten Gruppe" zurückzugeben.

Andere Alternativen für Pre-Java 7 waren:


( Original answer : Jan 2009 , wobei die nächsten beiden Links jetzt kaputt sind)

Sie können sich nicht auf eine benannte Gruppe beziehen, es sei denn, Sie codieren Ihre eigene Version von Regex ...

Genau das hat Gorbush2 in diesem Thread getan .

Regex2

(Eingeschränkte Implementierung, wie von tchrist ​​erneut hervorgehoben, da nur nach ASCII Bezeichnern gesucht wird. tchrist beschreibt die Einschränkung wie folgt:

sie können nur eine benannte Gruppe für denselben Namen haben (über die Sie nicht immer die Kontrolle haben!) und sie nicht für die In-Regex-Rekursion verwenden.

Hinweis: Beispiele für echte Regex-Rekursionen finden Sie in Perl- und PCRE-Regexen, wie in Regexp Power , PCRE-Spezifikationen und Strings mit ausgeglichenen Klammern abgleichen erwähnt rutschen)

Beispiel:

Zeichenfolge:

"TEST 123"

RegExp:

"(?<login>\\w+) (?<id>\\d+)"

Zugriff

matcher.group(1) ==> TEST
matcher.group("login") ==> TEST
matcher.name(1) ==> login

Ersetzen

matcher.replaceAll("aaaaa_$1_sssss_$2____") ==> aaaaa_TEST_sssss_123____
matcher.replaceAll("aaaaa_${login}_sssss_${id}____") ==> aaaaa_TEST_sssss_123____ 

(Auszug aus der Implementierung)

public final class Pattern
    implements Java.io.Serializable
{
[...]
    /**
     * Parses a group and returns the head node of a set of nodes that process
     * the group. Sometimes a double return system is used where the tail is
     * returned in root.
     */
    private Node group0() {
        boolean capturingGroup = false;
        Node head = null;
        Node tail = null;
        int save = flags;
        root = null;
        int ch = next();
        if (ch == '?') {
            ch = skip();
            switch (ch) {

            case '<':   // (?<xxx)  look behind or group name
                ch = read();
                int start = cursor;
[...]
                // test forGroupName
                int startChar = ch;
                while(ASCII.isWord(ch) && ch != '>') ch=read();
                if(ch == '>'){
                    // valid group name
                    int len = cursor-start;
                    int[] newtemp = new int[2*(len) + 2];
                    //System.arraycopy(temp, start, newtemp, 0, len);
                    StringBuilder name = new StringBuilder();
                    for(int i = start; i< cursor; i++){
                        name.append((char)temp[i-1]);
                    }
                    // create Named group
                    head = createGroup(false);
                    ((GroupTail)root).name = name.toString();

                    capturingGroup = true;
                    tail = root;
                    head.next = expr(tail);
                    break;
                }
255
VonC

Ja, aber es ist chaotisch, die Sun-Klassen zu hacken. Es gibt einen einfacheren Weg:

http://code.google.com/p/named-regexp/

named-regexp ist ein dünner Wrapper für die Standardimplementierung von regulären JDK-Ausdrücken mit dem einzigen Zweck, benannte Erfassungsgruppen im .net-Stil zu behandeln: (? ...).

Es kann mit Java 5 und 6 (Generika werden verwendet) verwendet werden.

Java 7 verarbeitet benannte Erfassungsgruppen, sodass dieses Projekt nicht von Dauer ist.

27
John Hardy

Für Leute, die zu spät kommen: Java 7 fügt benannte Gruppen hinzu. Matcher.group (String groupName) Dokumentation.

25
geofflane

Für Benutzer, die vor Java7 ausgeführt werden, werden benannte Gruppen von joni (Java-Port der Oniguruma Regexp-Bibliothek) unterstützt. Die Dokumentation ist spärlich, hat aber bei uns gut funktioniert.
Binärdateien sind über Maven erhältlich ( http://repository.codehaus.org/org/jruby/joni/joni/ ).

2
Ryan Smith

Was für ein Problem hast du mit jregex ? Es funktionierte gut für mich unter Java5 und Java6.

Jregex macht den Job gut (auch wenn die letzte Version aus dem Jahr 2002 stammt), es sei denn Sie möchten auf JavaSE 7 warten .

2
Brian Clozel

Eine etwas alte Frage, aber ich fand, dass ich diese auch brauchte und dass die obigen Vorschläge nicht ausreichend waren - und als solche - selbst eine dünne Hülle entwickelten: https://github.com/hofmeister/MatchIt

1