Page 1 of 1

Trim function

Posted: Tue May 21, 2024 5:39 pm
by Michael Vogel
Needed a trim function for multiple chars allowing case insensitive matches as well.

Here's the result, which could be easily tuned by using a predefined array to speedup the Ucase(Chr()) part...

Code: Select all

#CharMult=	#PB_Compiler_Unicode
#CharByte=	#CharMult+1

Procedure.s StrTrim(*s.Character,*trim.Character,DoCase=#True)

	Protected *c.Character
	Protected *l.Character
	Protected *r.Character
	Protected mode;char,chck
	
	Debug "----------------------------------------------------"
	Debug "Remove '"+PeekS(*trim)+"' with"+Left("out",1!DoCase*3)+" case:"
	
	*l=*s

	While *s\c
		*c=*trim
		If DoCase
			While *c\c
				If *s\c=*c\c
					mode+1
					Break
				EndIf
				*c+#CharByte
			Wend
		Else
			While *c\c
				If UCase(Chr(*s\c))=UCase(Chr(*c\c));   see text
					mode+1
					Break
				EndIf
				*c+#CharByte
			Wend
		EndIf
		*s+#CharByte

		Select mode
		Case 0;		
			mode=4;	
			*r=*s
		Case 1,3;		
			mode=2
			*l=*s
		Case 2,4;		
			mode=4;	
			*r=*s;	
		Case 5
			mode=4;	
		EndSelect
	Wend
	
	If *r<*l;			mode=2
		ProcedureReturn ""
	EndIf

	ProcedureReturn PeekS(*l,(*r-*l)>>#CharMult)

EndProcedure

s.s="****Purebasic is pure****"

Debug s

Debug StrTrim(@s,@"*")
Debug StrTrim(@s,@"*pure")
Debug StrTrim(@s,@"*PURE")
Debug StrTrim(@s,@"*PURE",#Null)

Re: Trim function

Posted: Tue May 21, 2024 11:03 pm
by idle
Think there's still an edge case, it removed the "*P" or is that the intended result?
----------------------------------------------------
Remove '*PURE' with case:
urebasic is pure
----------------------------------------------------

Re: Trim function

Posted: Wed May 22, 2024 1:20 am
by Demivec
idle wrote: Tue May 21, 2024 11:03 pm Think there's still an edge case, it removed the "*P" or is that the intended result?
----------------------------------------------------
Remove '*PURE' with case:
urebasic is pure
----------------------------------------------------
It's intentional. It trims any of the trim string's characters, in any order, from the beginning or end of the string. It stops when it encounters any character not in the trim string.

Re: Trim function

Posted: Wed May 22, 2024 1:49 am
by idle
Demivec wrote: Wed May 22, 2024 1:20 am It's intentional. It trims any of the trim string's characters, in any order, from the beginning or end of the string. It stops when it encounters any character not in the trim string.
Makes sense with your explanation.

Re: Trim function

Posted: Wed May 22, 2024 3:52 am
by jassing
Interesting approach, I had a similar need, but I used regex, which appeared about 30% faster...

Code: Select all

DisableDebugger

xincludeFile "StrTrim.pbi"

#iter = 100000
s.s="****Purebasic is pure****"
Define.s s1,s2,s3,s4

EnableDebugger
debug s
Debug StrTrim(@s,@"*")
Debug StrTrim(@s,@"*pure")
Debug StrTrim(@s,@"*PURE")
Debug StrTrim(@s,@"*PURE",#Null)

DisableDebugger
st = ElapsedMilliseconds()  
For x = 1 To #iter
  s1=StrTrim(@s,@"*")
  s2=StrTrim(@s,@"*pure")
  s3=StrTrim(@s,@"*PURE")
  s4=StrTrim(@s,@"*PURE",#Null)
Next
EnableDebugger
Debug "Strtrim() "+Str(ElapsedMilliseconds()-st)
Debug s
Debug s1
Debug s2
Debug s3
Debug s4


DisableDebugger

Procedure.s megaTrim( *string.Character, *filterChars.Character, bCaseSpecific=#True )
  Protected Dim result.s(0)
  Protected flags,newString.s,r;
  If Not bCaseSpecific : flags = #PB_RegularExpression_NoCase : EndIf 
  r=CreateRegularExpression( #PB_Any, "[^"+PeekS(*filterChars)+"].*[^"+PeekS(*filterChars)+"]",flags )
  
  If r 
    If ExtractRegularExpression( r, PeekS(*string), result() )
      newString=result(0)
    EndIf
    FreeRegularExpression(r)
  EndIf
  ProcedureReturn newString
EndProcedure

Debug s
Debug megaTrim(@s,@"*")
Debug megaTrim(@s,@"*pure")
Debug megaTrim(@s,@"*PURE")
Debug megaTrim(@s,@"*PURE",#False)
DisableDebugger
st=ElapsedMilliseconds()
For x = 1 To #iter
  s1=megaTrim(@s,@"*")
  s2=megaTrim(@s,@"*pure")
  s3=megaTrim(@s,@"*PURE")
  s4=megaTrim(@s,@"*PURE",#False)
Next
EnableDebugger
Debug "maxTrim() "+Str(ElapsedMilliseconds()-st)
Debug s
Debug s1
Debug s2
Debug s3
Debug s4

Re: Trim function

Posted: Wed May 22, 2024 4:21 am
by AZJIO
jassing wrote: Wed May 22, 2024 3:52 am Interesting approach, I had a similar need, but I used regex, which appeared about 30% faster...
string operations are slow

Code: Select all

UCase(Chr(*s\c))
try comparing case sensitive RTrimChar

Maybe it will be faster this way

Code: Select all

tmp$ = "*PURE"
tmp$ = LCase(tmp$) + UCase(tmp$)
s4=megaTrim(@s,@tmp$,#False)

Re: Trim function

Posted: Thu May 23, 2024 4:02 pm
by Piero
I know you will think I'm an idiot, but it amazes me to read good programmers discussing "30% faster" ways to trim multiple chars in 2024

Where are the """AI""" compilers? :?

Re: Trim function

Posted: Thu May 23, 2024 5:46 pm
by AZJIO
Piero wrote: Thu May 23, 2024 4:02 pm Where are the """AI""" compilers? :?
AI invented to control the AI ​​sect

Re: Trim function

Posted: Thu May 23, 2024 8:21 pm
by jassing
Piero wrote: Thu May 23, 2024 4:02 pm I know you will think I'm an idiot, but it amazes me to read good programmers discussing "30% faster" ways to trim multiple chars in 2024
It wasn't so much a comment on how fast my version was, but the fact that regex was faster than a custom string-by-reference, which should be faster.

But... as for 30% faster, when you're working with millions of records in a database, 30% can be the difference between an hour or 20 minutes. For human interaction, 300ms vs 100ms isn't noticeable.

Re: Trim function

Posted: Sun May 26, 2024 8:30 pm
by Piero
AZJIO wrote: Thu May 23, 2024 5:46 pm AI invented to control the AI ​​sect
The big-database sect; when you are stupid and think you can win by cheating, like reading stuff written on your hand during an exam