Seite 3 von 4

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 01.10.2011 19:13
von c4s
@STARGÅTE
Ich habe noch einen kleinen Fehler gefunden:

Code: Alles auswählen

Debug ReplacePattern("test", "test*", "X")  ; Gibt "test" aus anstatt "X"
(Unter Verwendung von: http://www.purebasic.fr/german/viewtopi ... 23#p293723 und ReplacePattern() aus http://www.purebasic.fr/german/viewtopi ... 06#p293606)

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 01.10.2011 21:19
von STARGÅTE
Jo, bestätig, ich hatte das nicht mehr drinne (* am Ende) weil es ja vorher nur ums Finden ging, und da sind * am ende egal, beim Ersetzen jedoch nicht, da du ja alles was mit "test" anfängt ersetzen willst.

Werd mich mal nach dem verlängerten Wochenende damit befassen.

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 01.10.2011 22:14
von c4s
STARGÅTE hat geschrieben:Werd mich mal nach dem verlängerten Wochenende damit befassen.
Danke!

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 02.10.2011 22:27
von STARGÅTE
So, müsste nun funktionieren, ich hoffe nur, dass jetzt nicht wieder eine andere Variante fehlschlägt.
Ich habe zusätzlich noch die DataSection entfernt und durch LCase ersetzt.
Das ist natürlich langsammer aber halt Unicodekompatibel.
(wusste garnicht, dass LCase("Δ") wirklich δ zurück gibt)

Code: Alles auswählen

Structure CharacterArray
	StructureUnion
		c.c[0]
		s.s{1}[0]
	EndStructureUnion
EndStructure

Procedure Pattern_Find(*String.CharacterArray, *Pattern.CharacterArray, *FoundLength.Integer=#Null)
	
	Protected StringIndex.i, PatternIndex.i, Position.i, TempPosition.i
	Protected FoundLength.i, TempFoundLength.i, BestFoundLength.i
	
	While *String\c[StringIndex]
		Repeat
			While *Pattern\c[PatternIndex]
				Select *Pattern\c[PatternIndex]
					Case '?' ; Platzhalter für genau ein Zeichen
						If *String\c[StringIndex+PatternIndex] = ''
							Break 2 ; Unpassend
						EndIf
					Case '#' ; Platzhalter für genau eine Zahl
						If *String\c[StringIndex+PatternIndex] < '0' Or *String\c[StringIndex+PatternIndex] > '9'
							Break 2 ; Unpassend
						EndIf 
					Case '*' ; Platzhalter für eine beliebige Anzahl von Zeichen (auch keins)
						While *Pattern\c[PatternIndex+1] = '*'
							PatternIndex + 1
							FoundLength + 1
						Wend
						Position = 0
						BestFoundLength = 0
						Repeat
							TempPosition = Pattern_Find(@*String\c[StringIndex+PatternIndex+Position], @*Pattern\c[PatternIndex+1], @TempFoundLength)
							TempFoundLength + FoundLength
							Position + TempPosition
							If *Pattern\c[PatternIndex+1] = '' And *String\c[StringIndex+PatternIndex] = ''
								Break 1 ; Passend
							ElseIf Not TempPosition
								If BestFoundLength
									FoundLength = BestFoundLength
									Break 2 ; Passend
								Else
									Break 3 ; Unpassend
								EndIf
							Else
								TempFoundLength + Position-1
								If *Pattern\c[PatternIndex+1] = ''
									While *String\c[StringIndex+TempFoundLength]
										TempFoundLength + 1
									Wend
								EndIf
								If TempFoundLength > BestFoundLength
									BestFoundLength = TempFoundLength
								EndIf
							EndIf
						ForEver
					Default ; Beliebiges anderes Zeichen
						If LCase(*String\s[StringIndex+PatternIndex]) <> LCase(*Pattern\s[PatternIndex])
							Break 2 ; Unpassend
						EndIf
				EndSelect
				PatternIndex + 1
				FoundLength + 1
			Wend
			If *FoundLength
				*FoundLength\i = FoundLength
			EndIf
			ProcedureReturn StringIndex+1
		Until #True
		PatternIndex = 0
		StringIndex + 1
		FoundLength = 0
	Wend
	
EndProcedure



Procedure FindPattern(String.s, Pattern.s, StartPosition=1, *FoundLength.Integer=#Null)
	
	Protected Result.i, *String.CharacterArray = @String
	
	If Not Pattern
		ProcedureReturn #Null
	ElseIf StartPosition > Len(String)
		ProcedureReturn #Null
	ElseIf StartPosition > 1
		Result = Pattern_Find(@*String\c[StartPosition-1], @Pattern, *FoundLength)
		If Result
			ProcedureReturn Result+StartPosition-1
		Else
			ProcedureReturn #Null
		EndIf
	Else
		ProcedureReturn Pattern_Find(@*String\c[0], @Pattern, *FoundLength)
	EndIf
	
EndProcedure



Procedure.s ReplacePattern(String.s, PatternToFind.s, StringToReplace.s)
	
	Protected Position, FoundLength
	
	Repeat
		FoundLength = 0
		Position = FindPattern(String, PatternToFind, Position, @FoundLength)
		If Position
			String = Left(String, Position-1)+Mid(String, Position+FoundLength)
			If Position > Len(String)
				String + StringToReplace
			Else
				String = InsertString(String, StringToReplace, Position)
			EndIf
			Position + Len(StringToReplace)
		EndIf
	Until Not Position
	
	ProcedureReturn String
	
EndProcedure



Procedure Replace(String.s, Pattern.s, StringToReplace.s="")
	Protected Text.s
	Text + LSet(Chr(34)+String+Chr(34), 20)
	Text + LSet(Chr(34)+Pattern+Chr(34),15)
	Text + Chr(34)+ReplacePattern(String, Pattern, StringToReplace)+Chr(34)
	Debug Text
EndProcedure




Replace("Hallo Welt!", "welt", "+-+")
Replace("Hallo Welt!", "?l", "+-+")
Replace("Hallo Welt!", "*l", "+-+")
Replace("Hallo Welt!", "!*", "+-+")
Edit: Bug-Fix

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 03.10.2011 11:48
von c4s
Danke schonmal. Aber folgendes geht immer noch nicht und ein weitere Fehler ist nun auch hinzugekommen:

Code: Alles auswählen

Replace("abc", "c*", "X")  ; Ergibt "abc" anstatt "abX" (siehe vorheriges Beispiel mit "test")
Replace("abc", "b*", "X")  ; Ergibt "aXc" anstatt "aX" (Nur mit neuem Code!)
Replace("abc", "*???*", "X")  ; Ergibt "abc" anstatt "X" (Neu entdeckt)

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 03.10.2011 13:27
von STARGÅTE
:oops: peinlich, peinlich.

Habe meinen Beitrag editiert, hatte eine +1 zu viel ^^ und eine Zeile zu viel.
Sollte nun gehen.
Aber ich wette fast du findest weitere Fehler :lol: , aber ist ja nicht schlimm, nur so wirds bugfrei :allright:

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 03.10.2011 15:43
von c4s
STARGÅTE hat geschrieben:Aber ich wette fast du findest weitere Fehler :lol: , aber ist ja nicht schlimm, nur so wirds bugfrei :allright:
Ja, hab da noch etwas auf Lager mit "**" :wink:

Code: Alles auswählen

Replace("abc", "?**b", "X")  ; Ergibt "abc" anstatt "Xc"
Replace("abc", "??**?", "X")  ; Ergibt "aX" anstatt "X"
Replace("abc", "???**?", "X")  ; Ergibt "X" anstatt "abc", dürfte nicht funktionieren

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 04.10.2011 19:31
von GPI
Gerade was gefunden:

http://msdn.microsoft.com/en-us/library ... 85%29.aspx

Windows liefert da eine Routine für :)

Code: Alles auswählen

 Debug PathMatchSpec_("Hallo.txt","*.txt")
 Debug PathMatchSpec_("Hallo.ess","*.txt")
 Debug PathMatchSpec_("Hallo.mp3","*.txt;*.mp3")
 Debug PathMatchSpec_("Hallo.txt","*.txt;*.mp3")
 Debug PathMatchSpec_("Hallo.ess","*.txt;*.mp3")
Funktioniert wie es soll.

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 05.10.2011 09:49
von c4s
@GPI
Danke für den Tipp.

Ich bin aber mit STARGÅTEs Funktion ganz zufrieden... vor allem weil es Potential zum erweitern hat und z.B. bereits "#" (für nur eine Zahl) unterstützt. Und es ist natürlich Plattformunabhängig!

Re: Funktion, die Platzhalter ("*" und "?") in String prüft

Verfasst: 05.10.2011 16:04
von GPI
du mußt halt aufpassen - ich hab keine Ahnung, ob * und ? in Linux reservierte Zeichen sind oder nicht tatsächlich auch als Dateinamen benutzt werden dürfen.

Hier hast du mit # schon das Problem, dass das Zeichen sehr wohl in einen Namen vorkommen kann, da es nicht verboten ist.