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:

Code: Alles auswählen

ProcedureDLL myProcedure(p1, p2, p3.s = "4,2")
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.
:shock: stimmt, daran habe ich ja gar nicht gedacht. Aber gut, dass Du darauf hingewiesen hast! :allright:

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 :allright:

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. [...]
Bild Klappt wunderbar. Vielen Dank! :allright:

@#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
GPI hat geschrieben:Für RegEx kann ich folgende Seite empfehlen:
https://regexr.com/
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
Kukulkan hat geschrieben:
GPI hat geschrieben:Für RegEx kann ich folgende Seite empfehlen:
https://regexr.com/
Die Seite ist gut, aber ich nutze auch oft diese:
https://regex101.com/
Beide Seiten nutze ich auch. Ich habe noch zwei weitere Lesezeichen:
http://regexhero.net/
http://txt2re.com/index-vb.php3