[bmx] some string stripping functions by hackball

Started by hackball, May 03, 2020, 02:22:55

Previous topic - Next topic

hackball

While starting to get into BMax i missed some functionality i got used to with BlitzBasic2/AmiBlitz on the Amiga so i hacked some of that into these little functions.They do string splitting, not by numchars but by strings. please have a look. test cases are at the end.
'myStringFuncs
'Adapted for Blitz2 compatibility and convenience by hackball


Function StripLeadStr:String (in:String, s:String)
?debug
    'Print"-------------------------------------------------------------"
    'Print "String : >" + in + "<  Length : " + Len(in) + "  Snip : >" + s + "<"
?
    Local out:String = ""
     i% = 0
   
    If Len (in) > 0
        'If in <> s           
            While in.StartsWith(s)
                in = Mid (in , Len(s)+1)
                ?debug
                    'Print in   
                ?
                i :+ 1
            Wend
            out = in
        'EndIf
    EndIf
    ?debug
    'Print " Loops : " + String(i)
    ?
    Return out
End Function

Function StripTrailStr:String (in:String, s:String)
?debug
    'Print"-------------------------------------------------------------"
    'Print "String : >" + in + "<  Length : " + Len(in) + "  Snip : >" + s + "<"
?
    Local out:String = ""
     i% = 0
   
    If Len (in) > 0
        'If in <> s           
            While in.EndsWith(s)
                in = Left (in , Len(in) - Len(s))
                ?debug
                    'Print in   
                ?
                i :+ 1
            Wend
            out = in
        'EndIf
    EndIf
    ?debug
    'Print " Loops : " + String(i)
    ?
    Return out
End Function

Function TrimSpaces:String (in:String)
?debug
    'Print"-------------------------------------------------------------"
    'Print "String : >" + in + "<  Length : " + Len(in)
?

    Local out:String = ""
    If in <> ""
        out = stripleadstr  (in," ")
        If out <> ""
            out = striptrailstr (out," ")
        EndIf
    EndIf
    Return out
End Function

Function TrimString:String (in:String, s:String)
?debug
    'Print"-------------------------------------------------------------"
    'Print "String : >" + in + "<  Length : " + Len(in) + "  Snip : >" + s + "<"
?

    Local out:String = ""
    If in <> ""
        out = stripleadstr  (in,s)
        If out <> ""
            out = striptrailstr (out,s)
        EndIf
    EndIf
    Return out
End Function

Function GetArgFromQuotedString:String (in:String , num:Int)    'returns parts of a ยด "arg1"   "arg2"  "argn"... `, including quotemarks! (or NULL)
?debug
    'Print"-------------------------------------------------------------"
    'Print "String : >" + in + "<  Length : " + Len(in) + "  Return Arg# : >" + String(num) + "<"
?
    Local out:String = ""
    Local targ$[]
    Local maxargs:Int = 0
   
    If in <> ""
        out = TrimString  (in," ")
        If out <> ""
            out = TrimString  (out,"~q")
            If out$ <> ""
                targ = out.Split("~q")
                If Len(targ) > 0        'we've got an temp array?
                    i% = 0
                    Local arg$[Len(targ)]
                    For t$ = EachIn targ
                        If TrimSpaces(t$) <> ""
                            arg[i] = t$
                            i :+1
                        EndIf
                        ?debug
                        'Print  " >" + t$ + "<"
                        ?
                    Next
                    i = 0
                    For t$ = EachIn arg
                        If t$ <> ""
                        ?debug
                            'Print String(i) + " >" + t$ + "<"
                            maxargs :+1
                        ?   
                        EndIf
                        i :+1
                    Next
                EndIf
            EndIf
        EndIf
    EndIf
    out = ""
    If maxargs <> 0        'warning: array starts at 0! 
    ?debug
        'Print "NumArgs : " + maxargs
    ?
        If (num > -1) And (num < maxargs)    'range is 0 -> maxargs-1
            out = arg[num]   
        EndIf
   
    EndIf
    Return out

End Function

Print
Print "* Testing StripLeadStr:String () *"
Print "Result = >" + StripleadStr ("  "," ") + "<"
Print "Result = >" + StripleadStr (" "," ") + "<"
Print "Result = >" + StripleadStr ("       AAA   "," ") + "<"
Print "Result = >" + StripleadStr ("BBBCCAABBCC","B") + "<"
Print "Result = >" + StripleadStr ("BBCCAABBCC","BB") + "<"
Print "Result = >" + StripleadStr ("Foo Fighters","Foo") + "<"

Print
Print "* Testing StripTrailStr:String () *"
Print "Result = >" + StripTrailStr ("  "," ") + "<"
Print "Result = >" + StripTrailStr (" "," ") + "<"
Print "Result = >" + StripTrailStr ("       AAA   "," ") + "<"
Print "Result = >" + StripTrailStr ("BBBCCAABBCC","C") + "<"
Print "Result = >" + StripTrailStr ("BBCCAABBCC","CC") + "<"
Print "Result = >" + StripTrailStr ("Foo Fighters"," Fighters") + "<"

Print
Print "* Testing TrimSpaces:String () *"
Print "Result = >" + TrimSpaces ("  ") + "<"
Print "Result = >" + TrimSpaces (" ") + "<"
Print "Result = >" + TrimSpaces ("       AA A   ") + "<"

Print
Print "* Testing TrimString:String () *"
Print "Result = >" + TrimString ("BBCCAABBCCBB","BB") + "<"
Print "Result = >" + TrimString ("~qQuotation~q","~q") + "<"
Print "Result = >" + TrimString ("Block by Block","Block") + "<"

Print
Print "* Testing GetArgFromQuotedString:String () *"
Print "Result = >" + GetArgFromQuotedString:String ("  ~qBB~q  ~qCC~q ~qAA~q  ~qBB   CC~q  ~qBB~q   ",1) + "<"
Print "Result = >" + GetArgFromQuotedString:String ("  ~qBB~q  ~qCC~q ~qAA~q  ~qBB   CC~q~qBB~q   ",3) + "<"

'eof

Derron

Thanks for your addition.


Had about 5 minutes to think about your code.
Your code does:
- use "Brl.Basic" (Left, Mid, Right) which is there for compatibility reasons (BlitzBasic etc). You are encouraged to use the "array based/slicing" access to strings: Left() = "mystring[.. count]", Mid() = "mystring[beginIndex .. endIndex]" and Right() = "mystring[mystring.length - count ..]"

- create new strings while processing (each "mid,left,right" creates a new string, same for above mentioned "slices")


This is why I created this (maybe bug containing) alternative to your first function:
Code (Blitzmax) Select

Function StripLeadStr:String (in:String, s:String)
local beginI:Int = 0
#LabelIn
For local inI:int = 0 until in.length
For local sI:Int = 0 until s.length
'not enough chars left to find another substring
if inI + sI >= in.Length Then Exit LabelIn
'input chars differ from substring
if in[inI + sI] <> s[sI] Then Exit LabelIn
Next
beginI :+ s.length
Next
if beginI = 0 then Return in
Return in[beginI ..]
End Function


It moves along the string, does array based comparisons and only "slices" if needed.

bye
Ron

degac

Hi
if you are using BlitzMax NG have a look at RegEx module... (or install for BlitzMax Vanilla).
Probably there are already solutions at your needs!
(after some testing and googling... RegEx syntax is not the best things in universe...)

' Match and capture group
' Extract fields from a string sorrouned by "

SuperStrict

Framework TEXT.RegEx
Import BRL.StandardIO

Local date:String = "~qaa~q ~qbb~q ~qcc dd~q ~qee~q"
Print "Original : " + date + "~n"

Local regex:TRegEx = TRegEx.Create("~q\~q.*?\~q")
Try

Local match:TRegExMatch = regex.Find(date)

While match

Print "~nDate -"
For Local i:Int = 0 Until match.SubCount()
Print i + ": " + match.SubExp(i)
Next

match = regex.Find()
Wend

Catch e:TRegExException

Print "Error : " + e.toString()
End

End Try

Print "Done."



(unless, of course, you want to learn BlitzMax ... in this case a good way to write from zero everything!)
If there's a problem, there's at least one solution.
www.blitzmax.org

hackball

Thanks for your ideas. I am new to BMax (at least as a regular coder) and i tend to write the function directly the second time i need it without a solution at hand.I cannot use BMax NG as there is no package available for Mac OS X, afaik. And it must run from 10.6 upto 10.9 Intel.


Derron

NG works on Mac OS (Brucey is a Mac user) - newer OS X just require you to build your BlitzMax binaries on your very own Mac OS. That is why there are some "scripts" for Mac users to run on their machines (it builds the binaries of NG then).

If you are interested in details: create a thread, reply in existing threads or join the BlitzMax NG discord channel.

bye
Ron