Domi: RegEx in Java

Hallo
Ich möchte einen Substring aus einem String entfernen und habe mir eine schöne RegEx zusammengebastelt, sie auf http://gskinner.com/RegExr/ getestet und dann in mein Programm eingefügt...dort kriege ich nun eine Fehlermeldung:

Exception in thread "main" java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 70
(?<=(99|T1|M2|M4|S2|S4|L2|G2|O6|Z6|O7|T5|M5|M3|P4|Q6|Q7|P9|T1|A8|F4){4})[A-Za-z0-9_]*

Mein String der zu prüfen ist hat folgenden Aufbau:
MM20_T1S2P999SAHH
(T1,S2,P9,99) können auch beliebige andere Paare sein, aus der RegEx-oderbedingung.
Mein Ziel ist es die Zeichenfolge SAHH zu ersetzen, sie ist jedoch nicht eindeutig... Im Grunde genommen, möchte ich einfach alles was hinter den 4 Paaren steht durch einen leeren String ersetzten und so weglöschen

Kann mir jemand helfen??
Ich komme nicht mehr weiter, wieso dass meine RegEx nicht geht

Vielen Dank schon mal

  1. Servus,

    [...]
    Exception in thread "main" java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 70
    (?<=(99|T1|M2|M4|S2|S4|L2|G2|O6|Z6|O7|T5|M5|M3|P4|Q6|Q7|P9|T1|A8|F4){4})[A-Za-z0-9_]*

    Das ist jetzt nur eine Vermutung, weil ich bei Capturing Groups und Lookahead / -behind immer ein wenig warmlaufen muss beim Überlegen, aber könnte es daran liegen, dass Du Deine OR-verbundenen Teilstrings als Capturing Group notiert hast, und das Ganze in einem lookbehind, der ja per se nicht mitgecaptured (sorry, finde kein schönes deutsches Wort) wird? Vielleicht geht es als non-capturing group: (?:X)
    -> http://java.sun.com/javase/6/docs/api/ -> Klasse Pattern

    Schöne Grüße,

    Peter

    1. Nachtrag: bei mir hat es mit einer non-capturing group auch nicht funktioniert. Allerdings läuft die folgende Regular Expression:
      .*(?<=99|T1|M2|M4|S2|S4|L2|G2|O6|Z6|O7|T5|M5|M3|P4|Q6|Q7|P9|T1|A8|F4{4})([A-Za-z0-9_]*)

      Ich habe am Anfang einfach mal auf .* gematched, weil ich nicht wusste, welche Zeichenfolge vor den vier Doppelzeichen erlaubt ist und welche nicht. Dann habe ich noch das eigentlich zu suchende Pattern als capturing group definiert, um es dann später rauszuschneiden.
      Hier noch kurz die Testklasse:

      import java.util.regex.Matcher;
      import java.util.regex.Pattern;

      public class Test
      {
          public static void main(String[] args)
          {
              String test = "MM20_T1S2P999SAHH";
              String regex = ".*(?<=99|T1|M2|M4|S2|S4|L2|G2|O6|Z6|O7|T5|M5|M3|P4|Q6|Q7|P9|T1|A8|F4{4})([A-Za-z0-9_]*)";
              Pattern pattern = Pattern.compile(regex);
              Matcher matcher = pattern.matcher(test);

      System.out.println(matcher.matches());

      String group = matcher.group(1);

      System.out.println(group);
          }
      }

      Schöne Grüße,

      Peter

      Servus,

      [...]
      Exception in thread "main" java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 70
      (?<=(99|T1|M2|M4|S2|S4|L2|G2|O6|Z6|O7|T5|M5|M3|P4|Q6|Q7|P9|T1|A8|F4){4})[A-Za-z0-9_]*

      Das ist jetzt nur eine Vermutung, weil ich bei Capturing Groups und Lookahead / -behind immer ein wenig warmlaufen muss beim Überlegen, aber könnte es daran liegen, dass Du Deine OR-verbundenen Teilstrings als Capturing Group notiert hast, und das Ganze in einem lookbehind, der ja per se nicht mitgecaptured (sorry, finde kein schönes deutsches Wort) wird? Vielleicht geht es als non-capturing group: (?:X)
      -> http://java.sun.com/javase/6/docs/api/ -> Klasse Pattern

      Schöne Grüße,

      Peter

      1. Hallo
        Besten Dank schon mal
        Aber dein Code macht nicht, dass es 4 Paare sein müssen, er findet SAHH auch wenns nur 3 Paare sind, es müssen aber zwingend 4 sein...
        Ich dachte die Klammer {4} sollte das erledigen...

        1. Hallo
          Besten Dank schon mal
          Aber dein Code macht nicht, dass es 4 Paare sein müssen, er findet SAHH auch wenns nur 3 Paare sind, es müssen aber zwingend 4 sein...
          Ich dachte die Klammer {4} sollte das erledigen...

          Nachtrag: Wie geht das dann, dass ich die RegEx einfach in String.replaceAll verwenden kann??
          Wenn ich das mache, ersetzt er den ganzen String und nicht nur SAHH...
          ersetzt er immer die group(0)??
          mfg

          1. Servus,

            [...]
            Nachtrag: Wie geht das dann, dass ich die RegEx einfach in String.replaceAll verwenden kann??
            Wenn ich das mache, ersetzt er den ganzen String und nicht nur SAHH...
            ersetzt er immer die group(0)??

            Das geht gar nicht, weil replaceAll eben das ganze Pattern matched. Wenn Du mit groups arbeiten willst / musst, dann kommst Du an der Pattern / Matcher Variante nicht vorbei. replaceAll ist intern ja auch nur ein shortcut dafür.

            Schöne Grüße,

            Peter

        2. Servus,

          [...]
          Aber dein Code macht nicht, dass es 4 Paare sein müssen, er findet SAHH auch wenns nur 3 Paare sind, es müssen aber zwingend 4 sein...
          Ich dachte die Klammer {4} sollte das erledigen...

          Ich denke, das liegt daran, dass die Einschränkung nur auf dem letzten Element liegt, also "[element 1] oder [element 2] oder [element 3] oder [element 4] oder ... oder vier Mal [letztes element der Liste]".
          Brauchst Du das unbedingt als lookbehind? Wenn nicht, dann könntest Du auch mit folgender Regex arbeiten:
          .*(99|T1|M2|M4|S2|S4|L2|G2|O6|Z6|O7|T5|M5|M3|P4|Q6|Q7|P9|T1|A8|F4){4}([A-Za-z0-9_]*)

          Dann ist Deine Zweierpärchenveroderung als capturing group definiert mit exakt vier Vorkommen, irgendwas davor und eine zweite Capturing group danach. Dabei muss dann aber auch die group mit der Nummer 2 abgefragt werden.

          Schöne Grüße,

          Peter

    2. Hmm hat genau den gleichen Fehler gegeben...
      Er hat Mühe mit dem {4} und sagt ja, das sei keine eindeutige Länge, aber es ist doch eindeutig??
      Wenn ich die Klammer mit den Paaren 4 Mal hintereinander hinkopiere dann gehts... aber ist nicht schön...
      gibts eine schöne möglichkeit??