String mit regulärem Ausdruck splitten?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

String mit regulärem Ausdruck splitten?

Beitrag 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
Hygge
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: String mit regulärem Ausdruck splitten?

Beitrag 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.
Bild
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: String mit regulärem Ausdruck splitten?

Beitrag 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
Hygge
Benutzeravatar
TroaX
Beiträge: 660
Registriert: 08.03.2013 14:27
Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Pop_OS! | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Pop_OS!
Wohnort: NRW
Kontaktdaten:

Re: String mit regulärem Ausdruck splitten?

Beitrag 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. ;)
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Pop_OS!
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Pop_OS!
NAS: Fritz.Box :lol:
Coding: Purebasic 6.04 | PHP | HTML | CSS | Javascript
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: String mit regulärem Ausdruck splitten?

Beitrag 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
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: String mit regulärem Ausdruck splitten?

Beitrag 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:
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: String mit regulärem Ausdruck splitten?

Beitrag 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
Hygge
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: String mit regulärem Ausdruck splitten?

Beitrag 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.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: String mit regulärem Ausdruck splitten?

Beitrag 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/
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: String mit regulärem Ausdruck splitten?

Beitrag 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
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Antworten