Regex Überschniedung von Ausdrücken

chalkbag

Bekanntes Mitglied
Hallo zusammen,


nehmen wir an ich habe folgenden String

Java:
str = "DV31DV32DV51DV52S205SA111A222"

aus diesem möchte ich mit folgenden regulären Ausdrücken

Java:
Pattern pat1= Pattern.compile("([a-zA-Z]{2}?[0-9]{2}?)");
Pattern pat3 = Pattern.compile("([a-zA-Z][0-9]{3}[a-zA-Z]?)");

folgendes Ergebnis erhalten

Code:
DV31
DV32 
DV51 
DV52 
SA11 
S205S 
A111
A222

Allerdings erhalte ich

Code:
DV31
DV32 
DV51 
DV52 
SA11 
S205S 
A111A

Das Problem ist das A111A erkannt wird, obwohl ich A111 und A222 gerne hätte.

Kann ich dem Matcher sagen das er nicht maximal munch sondern maximal fit verwenden soll?
Oder anders, A111A sollte er nur erkennen wenn das Folgezeichen auch ein [a-zA-Z] oder das Satzende ist?

Ich hoffe man versteht mich, vielen dank schonmal
 
günstig wäre Posten kompletten Codes und dein Beispiel hättest du etwas einfacher wählen können, pat1 ist letztlich doch egal?
ein weiteres ? soll angeblich genügsame Pattern bedeuten, folgendes scheint zu funktionieren:
Java:
public class Test {
    public static void main(String[] args)  {
        String str = "DV31DV32DV51DV52S205SA111A222";
        Pattern pat3 = Pattern.compile("([a-zA-Z][0-9]{3}[a-zA-Z]??)");
        Matcher m = pat3.matcher(str);
        while (m.find())   {
            System.out.println(m.group());
        }
    }

}
Code:
S205
A111
A222
edit: ok, dass beim S205 das hintere S fehlt ist auch nicht optimal..,
was anderes sehe ich leider nicht im Guten, Überschneidungen sind schon böse
 
Zuletzt bearbeitet von einem Moderator:
Hallo SlaterB,

vielen Dank für deine Antwort. Stimmt das erste Pattern hätte ich weglassen können und ich hätte es sicherlich noch entschlagen sollen. Aber du hast es ja verstanden :bae:

Ja, die Typen haben sich nachträglich geändert und bei deren Erstellung wurde keine Rücksicht genommen ob die sich eventuell RegEx-technisch überschneiden. So habe ich jetzt den Salat, wahrscheinlich muss ich jetzt mit der Hand nacharbeiten bei jedem Treffer, und schauen was das Nächste und Übernächste Zeichen ist. Natürlich sehr bäh :wuerg:, und ich hatte hier auf eine schönere Idee gehoft.

Vielleicht hat ja noch Jemand hier einen Heureka-Moment.

Trotzdem schonmal danke 🙂
 
Findet die ersten Paare nicht. Habe auch überlegt aber es scheint mit diesen Anforderungen nicht zu gehen. Wie soll SA11 und A111 gefunden, bzw welchen Sinn soll das ergeben?
 
Danke für die Antworten,

die Sinnfrage stellt sich nicht. Die Typen sind so definiert und ich kann keinen Einfluss darauf nehmen.
Ich denke es wird wirklich darauf hinauslaufen, dass ich manuell noch prüfen muss.
 
Gibt es denn irgendwelche weitere Regeln, wann etwas so oder so ausschaut? Z.B. dass es nur zwei Buchstaben am Anfang hat, wenn diese "DV" entsprechen.
 
Danke für die Antworten,

die Sinnfrage stellt sich nicht. Die Typen sind so definiert und ich kann keinen Einfluss darauf nehmen.
Ich denke es wird wirklich darauf hinauslaufen, dass ich manuell noch prüfen muss.

Was heißt "so definiert?" Welcher Regel unterliegen diese Typen? Und soll wirklich aus SA111 SA11 und A111 werden?
 
Regeln wären wie folgt

Typ 1: 2 Buchstaben und 2 Zahlen
Typ 2: 1 Buchstabe 3 Zahlen 1 Buchstabe
Typ 3: 1 Buchstabe 3 Zahlen

Mischung der Typen im entsprechenden Inhalt ist beliebig möglich.

Ich hätte mir gedacht, zuerst suche ich Typ 1 wie gehabt, anschließend Typ 3.
Dafür würde ich mit den üblichen Pattern danach suchen. Habe ich einen Treffer kontrolliere ich

1. Folgezeichen = EOF -> Typ 3
2. Fz 1 = Buchstabe + Fz 2 = Zahl -> Typ 3
3. Fz 1 = Buchstabe + Fz 2 = Buchstabe + Fz 5 = Buchstabe -> Typ3
Muss Typ 2 sein

(Kann gut sein das da noch ein paar Fälle fehlen, seh ich wohl erst zum Test)
 
Das kann man IMHO nur herausfinden, wenn man sich von rechts nach links arbeitet. Denn du kannst Typ 2 von 3 - im Fall, dass es da 2 Buchstaben am Schluss gibt - nur unterscheiden, wenn du weisst, ob beim nächsten Element Typ 1 oder ein anderer vorhanden ist. Wenn du aber von rechts nach links gehst, dann musst du nur von der aktuellen Position so viel nach Links, dass nach 2 Zahlen jeweils 2 und bei 3 Buchstaben jeweils 3 Zahlen folgen werden.
Irgendwie könnte man das sicher mit Regex lösen, allerdings gehts wohl einfacher "von Hand".
 
Aufbauend auf fjords Regex und leider nicht performant:

Java:
public class SplitRegex {

	public static void main(String[] args) {
		
		Set<String> found = new HashSet<String>();
		
		/**
		 * Typ 1: 2 Buchstaben und 2 Zahlen
		 * Typ 2: 1 Buchstabe 3 Zahlen 1 Buchstabe
		 * Typ 3: 1 Buchstabe 3 Zahlen 
		 */
		String str = "DV31DV32DV51DV52S205SA111A222";
		Pattern typ1 = Pattern.compile("([a-zA-Z]{2}[0-9]{2}|[a-zA-Z]\\d{3}(?:[a-zA-Z](?!\\d{3})(?![a-zA-Z]\\d\\d[a-zA-Z]))?)");
		Matcher matcher = typ1.matcher(str);
		int start = 0;
		while(matcher.find(start++)){
			found.add(matcher.group());
		}
		
		for (String string : found) {
			System.out.println(string);
		}
	
	}
}
 
ohne die Start Variable schaut das schon gut aus

Code:
S205S
A222
DV51
DV52
DV31
DV32
A111

mit start++ kommt bei mir

Code:
S205S
SA11  <-- der wurde so nicht angegeben
A222
DV51
DV52
DV31
DV32
A111

Sieht aber schon mal ganz gut aus, ich werde heute Nachmittag etwas rumspielen. Aber schonmal recht herzlichen Dank :applaus:
 

Zurück
Oben