Announcement

Collapse
No announcement yet.

replace a part of a delimited string

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Kev Peel
    replied
    ParseReplace function:

    http://www.powerbasic.com/support/pb...ad.php?t=23192

    Leave a comment:


  • William Burns
    replied
    I use a similar function. However you might want to add a little error checking in the code in case someone sends something unexpected. For example if they want to replace the 9th field in a string that only has 4 delimiters in it. In that case it should return the original string since their is nothing to replace. (unless you want it to add the extra delimiters needed first.) It will add a little time to the function, but not much.

    For example this would catch that issue:
    Code:
    FUNCTION ParsRepl2 (OrigString AS STRING, Delim AS STRING, FldNum AS LONG, ReplString AS STRING) AS STRING
       LOCAL r,n AS LONG
    
       if ParseCount(OrigString, Delim) => FldNum then
    
          FOR r=1 TO FldNum -1              'scan the string forwards to the required delim
             n=INSTR(n+1,OrigString,Delim)
          next r
          FUNCTION = LEFT$(OrigString,n)+ReplString+Delim+RIGHT$(OrigString,-INSTR(n+1,OrigString,Delim))
    
       else
          function = OrigString   'original string did not have enough delimiters so return original string
       end if
    END FUNCTION

    Leave a comment:


  • Paul Squires
    replied
    Originally posted by Paul Dixon View Post
    Erich,
    not fully tested but this is faster:
    Code:
    FUNCTION ParsRepl2 (OrigString AS STRING, Delim AS STRING, FldNum AS LONG, ReplString AS STRING) AS STRING
    LOCAL r,n AS LONG
    
    FOR r&=1 TO FldNum -1              'scan the string forwards to the required delim
        n=INSTR(n+1,OrigString,Delim)
    NEXT
    
    FUNCTION = LEFT$(OrigString,n)+ReplString+Delim+RIGHT$(OrigString,-INSTR(n+1,OrigString,Delim))
               
    END FUNCTION
    Paul.
    Nice example Paul - thanks! I'll use your code in some of my stuff for sure.

    Leave a comment:


  • John Gleason
    replied
    I see Paul did basically this above already, but hey, this includes a little test code.

    Code:
    #COMPILE EXE
    #DIM ALL
    
    FUNCTION ParsRepl (OrigString AS STRING, Delim AS STRING, FldNum AS LONG, ReplString AS STRING) AS STRING
    LOCAL Pieces() AS STRING
    
        DIM Pieces(1 TO PARSECOUNT(OrigString,Delim)) AS STRING
        PARSE OrigString, Pieces(), Delim
        Pieces(FldNum) = ReplString
        FUNCTION = JOIN$(Pieces(),Delim)
    
    END FUNCTION
    
    FUNCTION ParsReplFast (OrigString AS STRING, Delim AS STRING, FldNum AS LONG, ReplString AS STRING) AS STRING
    LOCAL cnt, cnt2, ii AS LONG
    
        FOR ii = 1 TO fldNum - 1
           cnt = INSTR(cnt + 1, origString, delim)
        NEXT
        cnt2 = INSTR(cnt + 1, origString, delim)
        FUNCTION = LEFT$(origString, cnt) & replString & MID$(origString, cnt2)
    
    END FUNCTION
    
    FUNCTION PBMAIN () AS LONG
    LOCAL TSV AS STRING, ii AS LONG, t, t2 AS QUAD
    
        TSV = BUILD$("Mary",$TAB,"had",$TAB,"a",$TAB,"little",$TAB,"lamb")
        TSV = BUILD$(TSV,TSV,TSV,TSV,TSV,TSV,TSV)
    '    PRINT TSV
        TIX t
        FOR ii = 1 TO 10000
           TSV = ParsRepl(TSV,$TAB,20,"young")
        NEXT
        TIX END t
    
        PRINT TSV, t
        PRINT
        TSV = BUILD$("Mary",$TAB,"had",$TAB,"a",$TAB,"little",$TAB,"lamb")
        TSV = BUILD$(TSV,TSV,TSV,TSV,TSV,TSV,TSV)
    '    PRINT TSV
        TIX t2
        FOR ii = 1 TO 10000
           TSV = ParsReplFast(TSV,$TAB,20,"young")
        NEXT
        TIX END t2
    
        PRINT TSV, t[COLOR="Red"]2[/COLOR]
        PRINT
        PRINT "so ParsReplFast was "; STR$(t / t2, 4); " times faster."
        WAITKEY$
    
    END FUNCTION
    Last edited by John Gleason; 6 Feb 2009, 07:18 PM. Reason: red 2

    Leave a comment:


  • Bern Ertl
    replied
    As long as the delimiter character is not included in any of the column data (like commas in quote encapsulated data for CSV files for example), Paul's code looks like it would work fine.

    Leave a comment:


  • Erich Schulman
    replied
    I was looking visually, but I am seeing better how it works now. I have plenty of rows I can test it on.

    Leave a comment:


  • Paul Dixon
    replied
    Erich,
    eh? My code scans forward to the one field you specify by FldNum and replaces it. Other fields should be unaffected.

    Paul.

    Leave a comment:


  • Erich Schulman
    replied
    From looking at the code, I don't think it will work with my real world data because two fields are too likely to contain the same data.

    Here is a real row, albeit edited for privacy.
    Code:
    8194	DORA	EXPLORER	11/07/02	06/19/89	00/00/00	23.25	.00	.00	.00	.00	.00	01/04/08	2267C	143.16	68	29.82	123-45-6789
    As you can see, several columns (7-12) contain ".00", and that is typical. But each of those columns can contain any value .00 through 99.99.

    It is very important only the correct column be updated. We don't want the IRS to have Swiper the Fox pay us a visit ("You'll never find your money now!").

    Leave a comment:


  • Paul Dixon
    replied
    Erich,
    not fully tested but this is faster:
    Code:
    FUNCTION ParsRepl2 (OrigString AS STRING, Delim AS STRING, FldNum AS LONG, ReplString AS STRING) AS STRING
    LOCAL r,n AS LONG
    
    FOR r&=1 TO FldNum -1              'scan the string forwards to the required delim
        n=INSTR(n+1,OrigString,Delim)
    
    NEXT
    
    FUNCTION = LEFT$(OrigString,n)+ReplString+Delim+RIGHT$(OrigString,-INSTR(n+1,OrigString,Delim))
               
    END FUNCTION
    Paul.

    Leave a comment:


  • Erich Schulman
    started a topic replace a part of a delimited string

    replace a part of a delimited string

    It works, so now let's make it better.

    Code:
    #COMPILE EXE
    #DIM ALL
    
    FUNCTION ParsRepl (OrigString AS STRING, Delim AS STRING, FldNum AS LONG, ReplString AS STRING) AS STRING
    LOCAL Pieces() AS STRING
    
        DIM Pieces(1 TO PARSECOUNT(OrigString,Delim)) AS STRING
        PARSE OrigString, Pieces(), Delim
        Pieces(FldNum) = ReplString
        FUNCTION = JOIN$(Pieces(),Delim)
    
    END FUNCTION
    
    FUNCTION PBMAIN () AS LONG
    LOCAL TSV AS STRING
    
        TSV = BUILD$("Mary",$TAB,"had",$TAB,"a",$TAB,"little",$TAB,"lamb")
        PRINT TSV
        TSV = ParsRepl(TSV,$TAB,4,"young")
        PRINT TSV
        WAITKEY$
    
    END FUNCTION
    The real world application will be calling ParsRepl tens of thousands of times, so how can I make it better? It is important all other fields be left unchanged.
Working...
X