FindString

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Velindos
Beiträge: 598
Registriert: 15.11.2010 10:56

FindString

Beitrag von Velindos »

Hallo Leute,

Möchte im Listicon einen Eintrag wie "K1" suchen. Wenn ich
Debug FindString("K11 mit Versatz", "K1",1, #PB_String_CaseSensitive)
anwende, kommen aber auch Ergebnisse mit "K11". Natürlich wenn ich

"K1 " einsetze wäre das behoben, aber dann liest er auch nicht "K1"!

Gibt es einen anderen Weg?

Gruss ... Velindos
Windows 7/8/8.1/10 (32/64-Bit) |Ubuntu 10.4 (64-Bit) |Purebasic 5.71 LTS (32/64-Bit)
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: FindString

Beitrag von NicTheQuick »

Mit RegularExpressions geht das ganz gut. Ich bin mir nur nicht sicher, ob ich mit den ReplaceString()-Zeilen alles abgedeckt habe, was als Sonderzeichen bei RegularExpressions vorkommen kann.

Code: Alles auswählen

Procedure FindStringEx(String.s, StringToFind.s, StartPosition.i = 1, Mode.i = #PB_String_CaseSensitive)
	Protected flag.i = 0, pos.i
	If Mode <> #PB_String_CaseSensitive
		flag = #PB_RegularExpression_NoCase
	EndIf
	StringToFind = ReplaceString(StringToFind, "\", "\\")
	StringToFind = ReplaceString(StringToFind, ".", "\.")
	StringToFind = ReplaceString(StringToFind, "[", "\[")
	StringToFind = ReplaceString(StringToFind, "]", "\]")
	StringToFind = ReplaceString(StringToFind, "(", "\(")
	StringToFind = ReplaceString(StringToFind, ")", "\)")
	StringToFind = ReplaceString(StringToFind, "^", "\^")
	StringToFind = ReplaceString(StringToFind, "$", "\$")
	Protected re.i = CreateRegularExpression(#PB_Any, StringToFind + "\s|" + StringToFind + "$", #PB_RegularExpression_MultiLine | #PB_RegularExpression_AnyNewLine | flag)
	
	If ExamineRegularExpression(re, String)
		While NextRegularExpressionMatch(re)
			pos = RegularExpressionMatchPosition(re)
			If pos >= StartPosition
				Break
			EndIf
			pos = 0
		Wend
	EndIf
	
	FreeRegularExpression(re)
	
	ProcedureReturn pos
EndProcedure

Debug FindStringEx("asdd K11 mit K.1 Versatz K1", "K.1", 1, #PB_String_CaseSensitive)
Bild
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: FindString

Beitrag von Josh »

Kommt natürlich drauf an, was für Kombinationen vorkommen können. Vielleicht genügt es schon, den zu durchsuchenden String um ein Leerzeichen zu ergänzen.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: FindString

Beitrag von ts-soft »

Velindos hat geschrieben:"K1 " einsetze wäre das behoben, aber dann liest er auch nicht "K1"!
Josh hat geschrieben:Kommt natürlich drauf an, was für Kombinationen vorkommen können. Vielleicht genügt es schon, den zu durchsuchenden String um ein Leerzeichen zu ergänzen.
Genügt nicht :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
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: FindString

Beitrag von NicTheQuick »

Alternativ kann man natürlich nach "K1 " suchen und wenn es nicht gefunden wurde nochmal prüfen, ob am Ende des Strings "K1" steht. Probleme gibt es dann aber (in meiner Version auch), wenn nach "K1" ein Komma oder ein Punkt folgt oder sonstige Zeichen, die weder Zahl noch Buchstabe sind.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: FindString

Beitrag von STARGÅTE »

@Nic:
Nein, du musst folgende Zeichen escapen:

Code: Alles auswählen

\ ^ $ { } [ ] ( ) . * + ? | < > - &
welche du übrigens auch mit einem Regex selber escapen kannst ;-) ohen den Zeilensalat da ^^
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
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: FindString

Beitrag von NicTheQuick »

Dann vielleicht so:

Code: Alles auswählen

Procedure FindStringEx(String.s, StringToFind.s, StartPosition.i = 1, Mode.i = #PB_String_CaseSensitive)
	Protected flag.i = 0, pos.i
	If Mode <> #PB_String_CaseSensitive
		flag = #PB_RegularExpression_NoCase
	EndIf
	Protected StringToFindEscaped.s
	Protected *c.Character = @StringToFind
	While *c\c
		Select *c\c
			Case '\', '^', '$', '{', '}', '[', ']', '(', ')', '.', '*', '+', '?', '|', '<', '>', '-', '&'
				StringToFindEscaped + "\" + Chr(*c\c)
			Default
				StringToFindEscaped + Chr(*c\c)
		EndSelect
		*c + SizeOf(Character)
	Wend
	Protected re.i = CreateRegularExpression(#PB_Any, StringToFindEscaped + "[^a-zA-Z0-9_-äöüÄÖÜß]|" + StringToFindEscaped + "$", #PB_RegularExpression_MultiLine | #PB_RegularExpression_AnyNewLine | flag)
	
	If ExamineRegularExpression(re, String)
		While NextRegularExpressionMatch(re)
			pos = RegularExpressionMatchPosition(re)
			If pos >= StartPosition
				Break
			EndIf
			pos = 0
		Wend
	EndIf
	
	FreeRegularExpression(re)
	
	ProcedureReturn pos
EndProcedure

Debug FindStringEx("asdd K11 mit K.1, Versatz K1", "K.1", 1, #PB_String_CaseSensitive)
Das ist natürlich nicht mehr so schnell wie FindString(), aber vielleicht reicht es dir ja. :wink:
Bild
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: FindString

Beitrag von Josh »

ts-soft hat geschrieben:Genügt nicht :wink:
Und warum nicht? Nach den Angaben von Velindos ist das nicht ausgeschlossen.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: FindString

Beitrag von ts-soft »

Steht in meinem Erstem Zitat! Velendinos hat das also ausgeschlossen.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: FindString

Beitrag von Josh »

ts-soft hat geschrieben:Steht in meinem Erstem Zitat! Velendinos hat das also ausgeschlossen.
Bitte meinen ersten Beitrag lesen. Ich sprach vom zu durchsuchenden String. Wenn Velindos wie von ihm vorgeschlagen in seinem Suchstring ein Leerzeichen anhängt und zusätzlich am zu durchsuchenden String, dann wird ein "K1" am Stringende auch gefunden.
Antworten