October 30, 2025, 12:21:38 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Extracting a string

Started by Brian, October 28, 2012, 12:12:52 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Brian

Hi,

I have strings similar to these:

"data","data","data","data","data","data","data","data","data","data",,"data",,"data","ANDREWS"
"data","data","data","data","data","data","data","data","data","data",,"data",,"data","HETA01KC02"
"data","data","data","data","data","data","data","data","data","data",,"data",,"data","KEARNEY"
"data","data","data","data","data","data","data","data","data","data",,"data",,"data","MCCW20KC02"

What I need to do is extract the names from the ends of the string. They SHOULD be all 10
characters, which would make it easy, but as you can see some are different lengths

How can I take the full string, work backwards until I find the first quote that starts the
string, and then extract the name string to a variable? Been beating my brains (those that
I have!) with this one

Thanks for any help,

Brian

aurelCB

Hi Brian.. :)
Do you need something like this( simple parser extractor):
'extract comma delimited arguments
WINDOW w1
STRING mline,t$
int y ,dy,cc
REM open the main window
OPENWINDOW w1,0,0,760,550,@MINBOX|@MAXBOX|@SIZE,0,"String functions",&main
Setwindowcolor w1,rgb(210,210,220):BACKPEN w1,RGB(210,210,220)
SETFONT w1,"Verdana",10, 400,0
'------------------------------------------
CONTROL w1,@Edit,"",120,40,620,22,0x50800000,1
SETFONT w1,"Verdana",8, 400,0,1
CONTROL w1,@sysButton,"Comma Count",200,120,200,26,0x50000000,2
CONTROL w1,@sysButton,"Del$.Pos + Show.Arguments",200,150,200,26,0x50000000,3
'test Tally(m$,d$)
'Move w1,10,10
'PRINT w1,"Test Tally: ",Tally(t$, ",")
DEF S1$ :STRING
DEF dl$,sRet$ :STRING
DEF dpos[16]:int
DEF pStr[16]:STRING





'sRet$ = MID$(S1$,j,(i-j))
'y=y+30
'Move w1,10,y:PRINT w1,sRet$
'-----------------------------------------

WAITUNTIL w1 = 0
END
'---

SUB main


IF @message = @IDCLOSEWINDOW
   CLOSEWINDOW w1
ENDIF
'for menu hendling
IF @message = @IDCONTROL

IF @CONTROLID = 2
IF @NOTIFYCODE=0
t$=GetControlText(w1,1)
cc=Tally(t$, ",")
Move w1,200,80
PRINT w1,"Test Tally: ",cc
ENDIF
ENDIF

IF @CONTROLID = 3
IF @NOTIFYCODE=0
Setwindowcolor w1,rgb(210,210,220):BACKPEN w1,RGB(210,210,220)
For i=1 to cc
dy=dy+30
Move w1,20,dy:print w1,dpos[i]
Next i
showArgs()
ENDIF
ENDIF


ENDIF

RETURN
ENDSUB
'------------------------------------------------------------
SUB showArgs
int k,i,j
't$= one ,
i = 0
j = 1
k = 1
y=0
FOR i = 1 TO LEN(t$)

           IF i=dpos[k]
k=k+1
                pStr[k] = MID$(t$,j,(i-j))
'remove quote -----------------------
IF LEFT$(pStr[k],1) = CHR$(34)
pStr[k] = MID$(pStr[k],2,LEN(pStr[k])-2)
ENDIF
'---------------------------------
y=y+30
Move w1,50,y:PRINT w1,pStr[k]           
            j = i + 1
        ENDIF
    NEXT i
'+extract last argument
k=k+1
pStr[k] = MID$(t$,j,LEN(t$))
y=y+30
Move w1,50,y:PRINT w1,pStr[k]

RETURN
ENDSUB
'-------------------------------------------------------------
'trim func
SUB Trim(inString:string),string
STRING res
res= LTRIM$(Rtrim$(inString))
RETURN res
ENDSUB



SUB Tally(STRING Main$,STRING Match$),INT
    DEF i,j,q,mlen,matchlen :INT
DEF t$:STRING
    mlen = LEN(Main$)
    matchlen = LEN(Match$)
    i = 1
    j = 0
    q = 0
    IF (mlen = 0) OR (matchlen = 0)
        RETURN j
    ENDIF
   
    WHILE 1

t$=MID$(Main$,i,matchlen)
IF t$ = CHR$(34) THEN q = q + 1
IF q=2 THEN q = 0
        IF t$ = Match$ AND q=0
           j = j + 1
'mem del$ position
dpos[j]=i
        ENDIF

           i = i + 1
        IF i > mlen
           Goto tbreak
        ENDIF
    WEND
Label tbreak
    RETURN j
ENDSUB



billhsln

See Split program written in Assembly by Ficko. Works great, all you would need to do is remove the quotes.

http://www.ionicwind.com/forums/index.php?topic=4231.msg32932#msg32932

Bill
When all else fails, get a bigger hammer.

aurelCB

Yeah,this Ficko program is fine but i'm not sure Bill what you mean that work great.
if you mean on speed ,no unfortunatelly there is no speed up over convencional (basic) coding.
belive me i have tried on many ,many ways speed up some things but simply nothing.
Small plus in my example is that that you have control over last extracted string
'+extract last argument
k=k+1
pStr[k] = MID$(t$,j,LEN(t$))
y=y+30
Move w1,50,y:PRINT w1,pStr[k]


which you can store in separate array.

billhsln

October 28, 2012, 03:40:19 PM #4 Last Edit: October 28, 2012, 03:43:04 PM by billhsln
W = Split(A$,",",StrPArray)
last = *<STRING>(StrPArray[W-1])
'remove "'s
last = mid$(last,2,len(last-2))


Does the same.

Not faster, unless you are parsing lots of data, which I do occasionally.

Bill
When all else fails, get a bigger hammer.

aurelCB

Yes Bill,you right - do the same thing but this is not presented in
original Ficko code ,right ?
Thanks for this addition to ;)

LarryMc

Always more than one way to skin a cat.
I use Fletchie's SplitTwo function
$include "ctl.inc"
openconsole
int i
string imp[4]
imp[0]="\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",,\"data\",,\"data\",\"ANDREWS\""
imp[1]="\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",,\"data\",,\"data\",\"HETA01KC02\""
imp[2]="\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",,\"data\",,\"data\",\"KEARNEY\""
imp[3]="\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",,\"data\",,\"data\",\"MCCW20KC02\""
print "Show original data"
Print
For i=0 to 3
print imp[i]
print
next i
Print "Show extracted names"
print
For i=0 to 3
print extractname( imp[i])
next i

print "Any key to end"
waitcon
closeconsole
end

sub extractname(string np),string
string left,right
'drop the trailing ""
np=left$(np,len(np)-1)
'get name
   SplitTwo(np,"\"",left,right,1,1)

return right
endsub
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

ckoehn

October 28, 2012, 06:53:18 PM #7 Last Edit: October 29, 2012, 07:59:03 PM by ckoehn
Here is some more things to play with.  :)

The Split takes multiple split characters at one time.
If there are more items than the array allows for, the last location contains the remainder of the string.

The RemoveChar does just that, it remove any characters that matches where ever it is in the string.

I use AddToNotepad for debugging.  

$INCLUDE "windowssdk.inc"

CONST MaxSplit=100

int n=0,i=0
string w[MaxSplit]=""
string imp[4]

imp[0]="\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",,\"data\",,\"data\",\"ANDREWS\""
imp[1]="\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",,\"data\",,\"data\",\"HETA01KC02\""
imp[2]="\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",,\"data\",,\"data\",\"KEARNEY\""
imp[3]="\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",\"data\",,\"data\",,\"data\",\"MCCW20KC02\""

FOR i=0 to 3

n=Split(imp[i],",",MaxSplit,w)

AddToNotepad("Number of Items in"+STR$(i)+":"+STR$(n))
AddToNotepad("Last Item: "+RemoveChar(w[n],CHR$(34)))

NEXT i

END

SUB Split(STRING txt,STRING ch,int array_size,string words[]),INT  'returns number of items in the array
INT ix,cnt=0
string item=""

FOR ix=1 to LEN(txt)
IF INSTR(ch,MID$(txt,ix,1))>0 AND cnt<(array_size-1)
words[cnt]=item
cnt++
item=""
ELSE
item+=MID$(txt,ix,1)
ENDIF
NEXT ix
words[cnt]=item

RETURN cnt
ENDSUB

SUB RemoveChar(string txt,string ch),string
int ix
string t=""

FOR ix=1 to LEN(txt)
IF INSTR(ch,MID$(txt,ix,1))=0
t+=MID$(txt,ix,1)
ENDIF
NEXT ix

RETURN t
ENDSUB

SUB AddToNotepad(string mtxt)
Long Success

Success=FindWindow("Notepad","Untitled - Notepad")
IF Success=0
SYSTEM "Notepad.exe"
Sleep(500) 'allow time to open
ENDIF

IDispatch objShell = CreateComObject("WScript.Shell")
Success = objShell.AppActivate("Untitled - Notepad")

IF Success
objShell.Sendkeys (mtxt+CHR$(13))
ENDIF
objShell->Release()

RETURN 0
ENDSUB


Later,
Clint

Brian

Hi,

Thanks for all your answers - I will look at them all. Speed is not really an issue, as
the function will only need to be called once, when the data is being run into the
database

Brian