Regulärer Ausdruck (x="y")

QXARE

Lt. Commander
Registriert
Aug. 2008
Beiträge
1.599
Regulärer Ausdruck - Schlüsselwertpaar

Hi,
ich sitz jetzt schon eine halbe Ewigkeit daran und schaff es mit RegEx einfach nicht, meine Frage jetzt ob das so überhaupt funktioniert wie ich es mir gedacht habe...

Als zu durchsuchender bzw. zu ersetzender String dient mir der Folgende:
Code:
'"a" = "b", "d" = 55.1, c="x", x=5'

Für jeden Beistrich der so ein Wertpaar trennt möchte ich nun ne zufällige Zahl einfügen, sprich diesen ersetzen. Es gibt aber die Möglichkeit den Beistrich im Schlüssel als auch im Wert zu definieren (nur wenn der jeweilige Teil im Hochkomma ist). Siehe:

Code:
"a,b" = "x,y" // +
a53k = 53.32 // +
54k = 43.23 // - weil der Schlüssel mit einer Zahl beginnt
a,b = "x,y" // -
"a,b" = x,y // -

Nun zum wichtigsten aller Dinge, der reguläre Ausdruck.

Für den Schlüssel habe ich
Code:
("[\S]+"|[a-z]{1}[a-z0-9_]*)
vorgesehen.
Bei der Zuweisung können sowohl links und rechts vom = Leerzeichen, Tabs oder sonst was sein:
Code:
[\s]*=[\s]*
und dann noch der Wert inklusive Beistrich
Code:
(".+"|[0-9]+\.?[0-9]*)[\s]*,
.

Ergibt:

Code:
'("[\S]+"|[a-z]{1}[a-z0-9_]*)[\s]*=[\s]*(".+"|[0-9]+\.?[0-9]*)[\s]*,'

Mir ist klar dass ich hier am Ende eines solchen Paares den Beistrich voraussetze, was aber erstmal egal sein sollte.

Was funktioniert jetzt nicht?

Solang ich als Wert eine Zahl nimm ersetzt er den Beistrich korrekt, wenn ich jetzt aber als Wert einen String definiere, wird der Beistrich ignoriert.

Falsch:
Code:
Eingabe: '"a" = "b", "d" = 55.1, c="x", x=5'
Ergebnis falsch: "a"="b", "d" = 55.1, c="x"ERSETZT x=5ERSETZT
Ergebnis richtig: "a"="b"ERSETZT "d" = 55.1ERSETZT c="x"ERSETZT x=5ERSETZT

Code:
Eingabe: '"a" = 421, "d" = 55.1, c=12, x=5'
Ergebnis richtig: "a"=421ERSETZT "d"=55.1ERSETZT c=12ERSETZT x=5ERSETZT

Würd mich freuen wenn sich einer kurz die Zeit nimmt, danke.
 
Zuletzt bearbeitet:
"?(?<![0-9])[a-zA-Z]{1}[a-zA-Z0-9]*"?[\s]*=[\s]*\S*?(,{1}|$)

Ist jetzt hingeschmiert, aber müsste so gehen. Die Capturing-Group beinhaltet dann entweder die Stelle deines Satzendes oder das Komma.

Edit: Ich habe da jetzt mal angenommen, dass Schlüssenamen in Anführungszeichen ebenfalls nicht mit Zahlen anfangen dürfen..

Edit2: Es kann natürlich sein, dass so eine Kombination wie '123"abc456" = ...' auftritt. Das wird hier natürlich falsch erfasst. da bräuchtest du ebenfalls noch einen negative lookbehind vor dem "?.

Edit3: Alle guten Dinge sind drei: Der Schlüsselwert ist bei mir alles, was nicht whitespace ist. Du kannst o.g. von dir einsetzen, aber es sollte für das Komma lazy sein.
 
Zuletzt bearbeitet:
Hi, erstmal danke für die schnelle Hilfe und super mit dem Beistrich zum Schluss :),
ich hab allerdings ein paar Fragen ^^.

Was stellt
Code:
(?<!
dar?

Als Wert sind in deinem Ausdruck jetzt alle Zeichen außer Leerzeichen und so erlaubt (würde auch super funktionieren) - falls es allerdings zwischen Anführungszeichen ist kann ein Text + Leerzeichen etc. drinnenstehen und dann gehts eben nicht mehr.

Ich glaub nur mit RegEx wird das Beispiel net zu lösen sein und ich muss den String mit einer Schleife durchforsten?

zu Edit: Doch, dürfen sie, solang sie eben in Anführungszeichen sind.
 
Also, das geht selbstverständlich mit RegEx, dafür ists ja da.

Was soll denn als Schlüsselwert erlaubt sind? Zahlen mit Punkten ohne Anführungszeichen und alles mit Anführungszeichen?

(".*?"|(?<=[\s,])(?<![0-9])[a-zA-Z][a-zA-Z0-9]*?)[\s]*=[\s]*\S*?(,{1}|$)

Das macht es jetzt schonmal besser und adressiert dein anderes Problem. Bei dem (?<! handelt es sich um einen negative lookbehind. Am besten liest du dir mal ein paar Grundlagen zu Regex durch, in Wikipedia sollte das erläutert sein.
 
Also als Schlüssel sind folgende Kombis erlaubt:
Code:
Alle Zeichen innerhalb der Anführungszeichen bis auf Leerzeichen, Tabulatoren usw. "([\S]*)"
Ohne Anführungszeichen, beginnend mit einem Buchstaben und ohne Sonderzeichen (nur Buchstaben oder Zahlen ([a-z]{1}[a-z0-9]*)

Für den Wert siehts so aus:
Code:
Alle Zeichen innerhalb der Anführungszeichen, auch ein leerer Wert ist möglich "(.*)"
Ohne Anführungszeichen, nur Dezimalwerte ([0-9]+\.?[0-9]*)

Wegen den look-behinds, muss ich immer überlesen haben weil ich die ganze Zeit auf Wiki häng xD, jedenfalls ist es mir nicht möglich diese zu verwenden weil ich nicht in PERL etc. programmiere.
Ergänzung ()

So hab das ganze jetzt mit ner Schleife gemacht. Ist zwar ein wenig länger^^, aber funktioniert. Danke trotzdem für deine Hilfe!

EDIT:

Ich habe ein Problem dass ich alleine wie es aussieht nicht mehr in den Griff bekomme - und zwar die Abgrenzung von Wert und Schlüssel.

Eingaben wie
Code:
"x"=4215.1231, j321="4891020000"4     12u49''"''!"§"''%!"§$"$§"&/ESYSF"
funktionieren.
Aber wenn jetzt beispielsweise
Code:
"x"="="y"
dasteht, dann wirft mein "Parser" einen Fehler, weil er glaubt dass als Schlüssel jetzt "x" dient und nicht "x"=".

Für mich verständlich dass der Fehler kommt, aber ich habe keine Ahnung wie ich hier zu einer Lösung komme.

Sicher kann ich = und , in Wert und Schlüssel verbieten, aber das ist nicht mein Ziel da man als Wert schnell einen Satz mit ein zwei Beistrichen und den dazugehörigen Delimitern verwenden kann. Die Kombination aus Delimiter und = oder , bereitet mir Sorgen :(

Vllt. weiss einer von euch mehr.
 
Zuletzt bearbeitet:
Zurück
Oben