Jump to content
Sign in to follow this  
nitro322

Recursion help

Recommended Posts

nitro322

I'm writing a function to parse a line from a CSV file. The particular CSV files I'm working with are delimited by commas, but add quote around fields that contain a ,. So, for example, it might contain the following line:

Test String1,var2,"Company, Inc.", Test String3

As you can see, something like a simple stringsplit() will not work here. Since I was unable to find any other UDFs specifically for handling this, I decided to write my own. I figured it'd be best to handle it as a recursive function, and I got the logic down to parse each field (the msgbox() line in the following code displays the correct strings when uncommented, in reverse order), but I can't figure out how to properly return it in an array. Basically, I can't figure how to pass the array and write to it during each recursive call, and then return the final product to the function call.

Below is a copy of my function, as well as some example code to test it. Any ideas how I can get the recursion handled properly? Thanks.

$line = 'Test String1,var2,"Company, Inc.", Test String3'
$splitline = _CSVSplit($line, 0)

for $i = 0 to ubound($splitline) - 1
    msgbox(0,"$splitline[" & $i & "]", $splitline[$i])
next

; function to split quoted CSV lines
func _CSVSplit($inline, $dim)
    dim $linearr[99]
    if stringleft($inline, 1) == '"' then
        $end = stringinstr($inline, '",', 0, 1)
        if not $end then
            $end = stringlen($inline)
            $linearr[$dim] = stringmid($inline, 2, $end - 1)
        else
            $linearr[$dim] = stringmid($inline, 2, $end - 2)
            $linearr[$dim+1] = _CSVSplit(stringtrimleft($inline, $end+1), $dim+1)
        endif
    else
        $end = stringinstr($inline, ',', 0, 1)
        if not $end then
            $end = stringlen($inline)
            $linearr[$dim] = stringleft($inline, $end)
        else
            $linearr[$dim] = stringleft($inline, $end - 1)
            $linearr[$dim+1] = _CSVSplit(stringtrimleft($inline, $end), $dim+1)
        endif
    endif
    msgbox(0,'test',$linearr[$dim])
    return $linearr
endfunc

Share this post


Link to post
Share on other sites
quaizywabbit

could you possibly check for the quote after stringsplit?

then where a quote is found at the beginning of an array item but without an endquote, concatenate each following array item until it finds the endquote.


[u]Do more with pre-existing apps![/u]ANYGUIv2.8

Share this post


Link to post
Share on other sites
/dev/null

Any ideas how I can get the recursion handled properly?  Thanks.

You won't need recursion. Try this.

$line = '"Test, String1",var2,"Company, Inc.", Test String3'

$splitline = _CSVSplit($line,",",'"') 

if @error = -1 then
   msgbox(0,"ERROR", "missing quote in string !!")
   exit
endif 


for $i = 0 to ubound($splitline) - 1
    msgbox(0,"$splitline[" & $i & "]", $splitline[$i])
next


func _CSVSplit($line,$delimiter,$escapechar)
    dim $split_strings[2]
    local $chars = StringSplit($line,"")

    local $token = ""
    local $tokencount = 1
    local $charcount = 1

    while $charcount <= $chars[0]

       switch $chars[$charcount]

         case $delimiter
            $split_strings[$tokencount] = $token
            $tokencount += 1
            redim $split_strings[$tokencount+1]
            $token = ""

         case $escapechar
            $charcount += 1
            while ($charcount <= $chars[0]) AND ($chars[$charcount] <> $escapechar)
                $token &= $chars[$charcount]
                $charcount += 1
            wend

           ;======= Open quote found =============================================
            if ($charcount > $chars[0]) AND ($chars[$charcount-1] <> $escapechar) then
                SetError(-1)
                return 0
            endif

         case else
            $token &= $chars[$charcount]
       endswitch

       $charcount += 1

    wend
    
    $split_strings[$tokencount] = $token
    $split_strings[0] = $tokencount

    return $split_strings

endfunc

EDIT: changed $marker1 -> $delimiter and $marker2 -> $escapechar

Cheers

Kurt

Edited by /dev/null

__________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *

Share this post


Link to post
Share on other sites
/dev/null

Perfect!  Thanks!

<{POST_SNAPBACK}>

You're welcome.

Cheers

Kurt


__________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×