Brauche Beratung wegen RegExp

PSP

Grünschnabel
Hallo! :)

Ich brauche mal ein bisschen Beratung von den RegExp Profis unter Euch. Und zwar habe ich ein Script geschrieben, in dem ich ziemlich viel Strings mittels RegExp Pattern geprüft werden. Dabei geht gerade unter Windows (wenn ich mir die Messung der Ladezeit so angucke) die Performance deftig in den Keller, da der String immer durch den nächsten RegExp geschickt wird, wenn der vorherige nicht matcht. Daher würde ich nun gerne alle unter einen Hut bringen. Frage ist nur hilft das was? Und wenn ja, nehmen wir mal als beispiel die folgenden möglichen Konstrukte:

[objekt=hund]
[foo=bar]
[foo=bar filter=bb]
[foo=bar parser=test]
[foo=bar parser=test filter=bb]

Wie kann ich jetzt in einem RegEx erreichen, dass:

1. Sich Filter und Parser nur dann dazu schalten lassen wenn der erste Teil ein foo und nicht objekt ist?
2. Wenn ich filter oder parser oder beides dazuschalten kann, im letzteren fall aber der parser IMMER vor dem Filter kommen muss?

Dabei möchte ich die Ausgabe des ganzen so einfach wie möglicht halten, damit ich mit dieser ohne weiteres weiterarbeiten kann.

Würde es ggf. irgendeinen Performanceschub bringen, wenn ich die Strings sagen wir mal nach [beliebiger inhalt] durchsuchen würde, dann nach " " und = splitte, und die Werte auf ihre Gültigkeit überprüfe und dann damit weiter arbeite? Oder sind RegEx als solche die performantere Variante (ich gehe jetzt mal von einem Ja aus?)?

Besten Dank schonmal ;)
 
Zuletzt bearbeitet:
Was meisnt du mit Objekt und var. Var ist alles was nicht dem String 'Objekt' entspricht? Also in deinem Beisplei foo?
 
Ähm ja, genau. K.a. warum ich mit var weitergeschrieben hab, da müsste jetzt foo stehen. Gleich mal editieren... ;)

Wobei foo in dem Fall aber Konstant wäre. Kann auch [var, [html, ... haben.
 
So auf die schnelle
Code:
\[(?:objekt=([[:alnum:] ]*)|foo=([[:alnum:]]+)[ ]?(?:parser=([[:alnum:] ]*)|)[ ]?(?:filter=([[:alnum:] ]*)|))\]
Hier mein Test:
http://regexp-evaluator.de/evaluator/85351be04519326f8eb74776db7ba5ae/#ergebnis

Ergibt das Resultat
Index1: Obejkte; Index 2: Inhalt von foo; Index 3: Inhalt von parser; Inhalt 4: Inhalt von filter
Code:
Array
(
    [0] = Array
        (
            [0] = [objekt=hund]
            [1] = [foo=bar]
            [2] = [foo=bar filter=bb]
            [3] = [foo=bar parser=test]
            [4] = [foo=bar parser=test filter=bb]
        )
    [1] = Array
        (
            [0] = hund
            [1] = 
            [2] = 
            [3] = 
            [4] = 
        )
    [2] = Array
        (
            [0] = 
            [1] = bar
            [2] = bar
            [3] = bar
            [4] = bar
        )
    [3] = Array
        (
            [0] = 
            [1] = 
            [2] = 
            [3] = test
            [4] = test 
        )
    [4] = Array
        (
            [0] = 
            [1] = 
            [2] = bb
            [3] = 
            [4] = bb
        )
)
 
Zuletzt bearbeitet:
Macht es die Sache nicht performanter, wenn Du lediglich einmal den Regex rüberlaufen lässt, um Dir Key=Value-Paare erstellen zu lassen? Die Entscheidung, was mit den Daten passiert kann doch auch ohne Regex geschehen.

Code:
#([a-z]+)=([a-z]+)#

(Sorry, hab jetzt nur auf Buchstaben begrenzt, yaslaws :alnum: ist die sinnvollere Auswahl :D)
 
@chmee: Genau das ist ja mehr oder weniger Ziel! Leider ist es mit deinem Code nicht getan, da die Values abhängig vom Key auch nochmal auf gewisse Strukturen überprüft werden sollen.

@yaslaw: Das bringt mich schonmal ein ganzes Stück weiter, danke. Was genau macht das : hinter dem ? Irgendwie finde ich da nix zu...
 
PSP: Hmm, Ergibt sich denn nicht schon aus der Menge der Treffer eine gewisse weitere Arbeitsweise?
Wenn count($regex_treffer[0])=1, dann scheint es ein einfaches objekt=hund zu sein - wenn aber key[0] anstatt objekt ein foo ist, dann ergeben sich weitere key/value-Paare, die den Rest des Arrays füllen. Mir stellt sich die Frage nur, ob es im Nachhinein leichter ist, mit einem key/value-Array zu arbeiten, oder einem "losen" Gefüge aus (sorry) yaslaws Ergebnis.

mfg chmee
 
@ chmee: Nein, mit Anzahl der Parameter darf man da gar nicht beigehen. Sagen wir mal ich würde folgendes machen:

[objekt=hund]
[objekt=hund rasser=labrador]
[foo=bar]
[foo=bar filter=irgendwas]

Dann hätte ich in beiden Fällen max 2. key=value paare, die ich dann wieder nicht wüsste worum es sich jetzt genau handelt und die Treffer auch noch durch weitere RegExp auf ihre Gültigkeit prüfen müsste, da filter z.b. Zahlen enthalten kann, eine Hunderasse aber nicht, das würde das ganze nur wieder verkomplizieren.

Das von yaslaws ist schon ganz gut, denn ist der String [objekt=hund], so ist $erg[1] = hund. Bei [foo=bar] wäre $erg[1] aber leer und $erg[2] wäre bar. Folglich kann ich hier anhand der Indizes des Arrays erkennen worum es sich bei dem Treffer handelt und bei bedarf weitere Folgeindizes mit einbeziehen. Was man jetzt nur noch überprüfen müsste ist ob object öffter geparsed wird als foo, und es entsprechend weiter hinten oder vorne im Pattern platzieren.
 
Zurück