Seite 1 von 2
String mit regulärem Ausdruck splitten?
Verfasst: 27.09.2017 20:20
von Kiffi
Hallo,
ich stehe vor der Aufgabe, einen Teil-String in einzelne Bestandteile zu splitten.
Beispiel:
Hier möchte ich gerne die Auflistung aller Parameter erstellen:
* p1
* p2
* p3.s = "4,2"
Mit StringField mit Komma als Delimiter kann ich nicht arbeiten, weil hier im p3.s - Defaultwert auch ein Komma vorkommen kann.
Ich denke, dass man das Ganze recht schnell mit einem regulären Ausdruck lösen könnte. Allerdings stehe ich mit regulären Ausdrücken auf dem Kriegsfuß. Könnte mir deshalb freundlicherweise jemand unter die Arme greifen?
Grundgerüst:
Code: Alles auswählen
EnableExplicit
Define regex_Parameter
Define ProcedureLine.s
ProcedureLine = ~"ProcedureDLL myProcedure(p1, p2, p3.s = \"4,2\") ; just a comment, one, two, three"
regex_Parameter = CreateRegularExpression(#PB_Any, "SomethingMagicHappensWithWeirdCharacters")
If ExamineRegularExpression(regex_Parameter, ProcedureLine)
While NextRegularExpressionMatch(regex_Parameter)
Debug RegularExpressionMatchString(regex_Parameter)
Wend
FreeRegularExpression(regex_Parameter)
EndIf
Wichtig ist, dass der reguläre Ausdruck mit allen Arten von PureBasic-Parametern zurecht kommen muss und dass am Ende der Prozedur natürlich auch ein Kommentar stehen könnte.
Danke im Voraus & Grüße ... Peter
Re: String mit regulärem Ausdruck splitten?
Verfasst: 27.09.2017 21:01
von NicTheQuick
Das ist gar nicht so einfach. Immerhin kann der Default-Wert bei einem String auch wieder einer der Form ~"" sein. Darin können wieder Anführungszeichen vorkommen. Ich glaube mit einer normalen RegEx kommt man da nicht weit oder sie wird unheimlich komplex.
Re: String mit regulärem Ausdruck splitten?
Verfasst: 27.09.2017 21:12
von Kiffi
NicTheQuick hat geschrieben:Immerhin kann der Default-Wert bei einem String auch wieder einer der Form ~"" sein.

stimmt, daran habe ich ja gar nicht gedacht. Aber gut, dass Du darauf hingewiesen hast!
Danke & Grüße ... Peter
Re: String mit regulärem Ausdruck splitten?
Verfasst: 27.09.2017 21:44
von TroaX
Ich würde im ersten Schritt die Strings herauslösen und gegen eindeutige Platzhalter (Token) austauschen:
https://www.regular-expressions.info/ex ... ammer.html
Danach kannst du mit Stringfield die Parameter rauslösen. Ich würde auch nicht immer versuchen, alles direkt in einem Reg-Expression zu machen. Lieber in Einzelaufgaben aufteilen und dann Schritt für Schritt.

Re: String mit regulärem Ausdruck splitten?
Verfasst: 28.09.2017 00:07
von Kurzer
Hallo Kiffi,
zwar unoptimiert und ohne Pointerzugriff, aber soweit funktionabel - auch für komplexere Parameter.
Code: Alles auswählen
EnableExplicit
Global Dim sParams.s(10)
Procedure.s Extract(sString.s)
Protected.i i, iParamNum, iParsing = 0, iQuote = -1
Protected sChar.s{1}
; Den String von links Zeichen für Zeichen scannen
For i = 0 To Len(sString) - 1
sChar = PeekS(@sString + i*SizeOf(Character), 1)
If sChar = "("
; Sobald wir uns zwischen ( und ) befinden, wird die Analyse begonnen
If iParsing < 1 : sChar = "" : EndIf
iParsing + 1
ElseIf sChar = ")"
; Sobald wir uns nicht mehr zwischen ( und ) befinden, wird die Analyse beendet
iParsing - 1
If iParsing = 0 : Break : EndIf
ElseIf sChar = ~"\""
; Innerhalb von Anführungszeichen beachten wir keine Kommas
iQuote * -1
ElseIf sChar = ~"," And iQuote = -1 And iParsing = 1
; Bei einem Komma außerhalb von Anführungszeichen auf Parsinglevel 1 wechseln wir zum nächsten Arrayeintrag
iParamNum + 1
sChar = ""
EndIf
; Zeichenweises Kopieren des Parameters in das aktuelle Array-Element
If iParsing > 0
sParams(iParamNum) + sChar
EndIf
Next i
For i = 0 To iParamNum
Debug sParams(i)
Next i
EndProcedure
;Extract(~"ProcedureDLL myProcedure(p1, p2, p3.s = \"4,2\") ; just a comment, one, two, three")
;Extract(~"ProcedureDLL myProcedure(p1, p2, p3.s = \"4,2\", p4.s = GetValue(8)) ; just a comment, one, two, three")
;Extract(~"ProcedureDLL myProcedure(p1, p2 = 3.14, p3.s = \"4,2\", p4.s = GetValue(8)) ; just a comment, one, two, three")
Extract(~"ProcedureDLL myProcedure(p1, p2 = GetString(\"3,14\", \"Test\", 42), p3.s = \"4,2\", p4.s = GetValue(8)) ; just a comment, one, two, three")
Liefert:
[00:04:28] [Debug] p1
[00:04:28] [Debug] p2 = GetString("3,14", "Test", 42)
[00:04:28] [Debug] p3.s = "4,2"
[00:04:28] [Debug] p4.s = GetValue(8)
Gruß Kurzer
Re: String mit regulärem Ausdruck splitten?
Verfasst: 28.09.2017 08:09
von #NULL
im englischen forum war vor kurzem eine aehnliche frage, da wollte jemand sowas parsen (leerzeichen-getrennte liste aus [geschachtelten] funtionsaufrufen) :
"c(b(a())) c(b(a())) c(a(), b())"
das konnte ich mit rekursiver regex bewerkstelligen:
http://www.purebasic.fr/english/viewtop ... 58#p511858
vielleicht kann man das hier auch anwenden, allerdings ist da noch kein string handling enthalten.
aber der code von kurzer funktioniert ja schon und ist auch noch sehr schlank

Re: String mit regulärem Ausdruck splitten?
Verfasst: 28.09.2017 13:23
von Kiffi
Kurzer hat geschrieben:zwar unoptimiert und ohne Pointerzugriff, aber soweit funktionabel - auch für komplexere Parameter. [...]

Klappt wunderbar. Vielen Dank!
@#NULL: Auch einen Dank an Dich für Deine Antwort! Ich präferiere Kurzers Code, weil ich da einen besseren Durchblick habe.
Grüße ... Peter
Re: String mit regulärem Ausdruck splitten?
Verfasst: 28.09.2017 21:39
von GPI
Für RegEx kann ich folgende Seite empfehlen:
https://regexr.com/
damit hat man nicht nur links die Erklärungen, sondern kann dann oben auch gleich ausprobieren. Der Text lässt sich auch editieren. Allerdings ist die Aufgabe nicht einfach.
Re: String mit regulärem Ausdruck splitten?
Verfasst: 29.09.2017 08:26
von Kukulkan
Die Seite ist gut, aber ich nutze auch oft diese:
https://regex101.com/
Re: String mit regulärem Ausdruck splitten?
Verfasst: 29.09.2017 08:58
von RSBasic
Beide Seiten nutze ich auch. Ich habe noch zwei weitere Lesezeichen:
http://regexhero.net/
http://txt2re.com/index-vb.php3