[Regex] Gruppen wieder zusammenführen

joschilein

Multitalent
ID: 9301
L
5 Mai 2006
1.393
151
Aus den möglichen Zielstrings wie
Code:
ABC1234
ABC12 34
möchste ich das Split-Ergebnis
Code:
ABC
1234
haben.

Der Versuch
Code:
([A-Za-z]{3})(\d{2})\040?(\d{2})
liefert aber drei Teile:
Code:
ABC
12
34
Ich möchte also Teil 2 und 3 als ein Stück zurück bekommen.

PS: Ja, mir ist bekannt, dass ich das auch hinterher per PHP einfach zusammen pappen könnte 8)
Ich möchte aber den Regex-Weg wissen.
 
Einfach eine "Über-Gruppe" einbauen und die dann nehmen. Um Speicher zu sparen, dann noch die zwei anderen Gruppen als "non-capturing" definieren. Achja, außerdem müssen Backslashes in PHP escapet werden (bzw. sollten, auch wenn es wie in diesem Fall so funktioniert):

PHP:
$regex = '#([A-Za-z]{3})((?:\\d{2})\\040?(?:\\d{2}))#';

Außerhalb von PHP natürlich
Code:
([A-Za-z]{3})((?:\d{2})\040?(?:\d{2}))

edit: Natürlich kannst du, wie happymaster schrieb, die inneren Gruppen auch gleich weglassen ;) :wall:
 
@happymaster: Das Leerzeichen soll aber nicht im Ergebnis enthalten sein :!:

(Mit Leerzeichen hätte ich es auch hinbekommen :roll: )

PS: Ähm wegen escapen.. Ich mach grad noch mit Regex Coach rum
 
Hm.. warum willst du es denn nicht per PHP machen?
So wie du es hast ist es doch schon gut.. einfach $1 und $2$3 nehmen.. dann ist es doch zusammen...

PS: Wenn du alles immer in PHP testest, lad dir mal das Programm Kodos. Damit kann man das schnell alles prüfen.
 
(\d{2}(?:\040)?\d{2})

Sollte es doch tun. @happymaster hab mich mal getraut "copy & past"
wobeich es so machen würde.
(\d(?:\040)?\d?) Sonst erkennt der doch den ersten string nicht
 
Das bewirkt ja nur, dass keine weitere Gruppe entsteht, aber in der umschließenden Gruppe ist das Leerzeichen natürlich immer noch vorhanden.
 
Mein eigentlicher Zielstring ist natürlich etwas komplizierter, als der angegebene "ABC1234"-String. Ich hatte die Anforderungen noch nicht ganz gelesen und dann festgestellt, dass ich auch noch Informationen brauche, die teilweise aus Teilmengen bisheriger Gruppen gehen, das ganze ist mir dann mit Regex doch viel zu kompliziert. Bei dem Problem verwende ich jetzt nur noch ein Regex, das die grundlegende Struktur überprüft und die einzelnen Teile bastel ich mir dann mit reinen PHP-Mitteln.

Aber mich würde trotzdem noch interessieren, ob es irgendwie möglich wäre Gruppen zu vereinigen. Oder auch, ob man per Referenz auf eine Gruppe zugreifen kann, ohne dass die Gruppe ausgegen wird (Beispielsweise gibt es mehrere mögliche Leerstellen, aber entweder sollen alle oder gar keine vorhanden sein). Bei der reinen Strukturüberprüfung kann man das ja leicht als Referenz angeben, da braucht man ja nur eine boolsche Antwort.
 
Ich hab auch mal rumprobiert mit verschiedenen Ansätzen:
  • erster Gedanke mit Assertions
    PHP:
    $withspace_regex='([A-Za-z]{3})(\d{2})(?=\040)(\d{2})';
    Hier ist aber das Problem, dass der "Matching-Cursor" dann auf der Stelle stehen bleibt und der Ausdruck dann überhaupt nicht matcht, weil statt der 2 Ziffern dann das Leerzeichen steht.
  • zweiter Versuch mit Condition-Pattern
    PHP:
    $string="ABC12 34";
    $withspace_regex='([A-Za-z]{3})(\d{2})\040(\d{2})';
    $withoutspace_regex='([A-Za-z]{3})(\d{2})(\d{2})';
    
    $regex="(?(?=$withspace_regex)$withspace_regex|$withoutspace_regex)";
    
    preg_match('/'.$regex.'/i',$string,$matches);
    
    header("content-type: text/plain");
    print_r($matches);
    War auch nix, weil ich da dasselbe Problem hab, wie wenn ich einfach \040? setz.
  • noch ein Versuch mit Condition-Pattern
    Dann hab ich mir überlegt, ob es mir was bringt, wenn ich weiß, ob das Leerzeichen drin is oder nicht:
    PHP:
    $regex='([A-Za-z]{3})(\d{2})(\040)?(?(3)(\d{2})|(\d{2}))';
    Toll, funktioniert, aber gecaptured is gecaptured. Wenn das Leerzeichen einmal drin is, krieg ich es nicht mehr raus.
Fazit:
Ob das überhaupt funktionieren kann, dass ich in einen Ausdruck ein "Loch" (Überspringen von Zeichen) einbauen kann... Ich weiß ned, obs da überhaupt ne Lösung geben kann :think:
 
vielleicht sollte man sich erst mal die frage stellen was reguläre ausdrücke sind... meiner meinung nach ist es nicht ziel von regulären ausdrücken ein text zu formatieren, sondern zu prüfen ob ein text in ein gewisses muster passt.