String Substitute ALL?

Discussion in 'AutoCAD' started by David Kozina, Jul 27, 2004.

  1. David Kozina

    David Kozina Guest

    Since vl-string-subst only replaces the first occurrence of a pattern match,
    does anyone know of a good way to replace ALL occurrences of a pattern
    match?

    Best regards,
    David Kozina
     
    David Kozina, Jul 27, 2004
    #1
  2. I wrote this one for my toolbox.

    ; function to remove a character or set of characters
    ; from a string. This is case a sensitive function.
    ; Arguments:
    ; [string] - string to search
    ; [remove] - string to remove
    ; Example:
    ; (removeStr "ABCDEFABCXYZ" "ABC") -> "DEFXYZ"
    ; (removeStr "ABCDEFABCXYZ" "AbC") -> nil
    (defun removeStr (string remove)
    (while (vl-string-search remove string)
    (setq string (vl-string-subst "" remove string))
    )
    string
    )
     
    Jason Piercey, Jul 28, 2004
    #2
  3. David Kozina

    John Uhden Guest

    ;;------------------------------------------------
    ;; Function added 12-01-00 (not used anywhere yet)
    (defun @cv_strsubst_all (new old what / l n)
    (setq l (strlen new) n 0)
    (while (setq n (vl-string-search old what n))
    (setq what (vl-string-subst new old what n)
    n (+ n l)
    )
    )
    what
    )
     
    John Uhden, Jul 28, 2004
    #3
  4. David Kozina

    David Kozina Guest

    Shoot, you got my hopes up there, Terry - I was thinking "now how did I go
    and miss THAT function?"

    'cept it only does a 1:1 character substitution - which doesn't work for
    this task - sorry.

    I had attempted one before I posted, trying to iterate (vl-string-subst...)
    until the modified string = the original string (ie - no change) but when I
    tried something like:
    Replace "A" with "AA" in "ALI BABA" - (with the Old Pattern = a subset of
    the New Pattern) it would cause a stack overflow. :(

    And I couldn't figure out a way to just iterate through the string once.

    Best regards,
    David Kozina
     
    David Kozina, Jul 28, 2004
    #4
  5. David Kozina

    David Kozina Guest

    Jason,

    Thanks.

    However, I was looking more for a global string substitution, rather than
    removal, per se.

    BTW, I found one of the code's commented examples to be sort of scary...

    ; (removeStr "ABCDEFABCXYZ" "AbC") -> nil :-@

    But after actually testing it (to make sure), I found it worked "as it was
    supposed to"
    (removeStr "ABCDEFABCXYZ" "AbC") -> "ABCDEFABCXYZ" - Whew!

    Best regards,
    David Kozina
     
    David Kozina, Jul 28, 2004
    #5
  6. David Kozina

    David Kozina Guest

    John,

    Thanks very much! That seems to do the job.

    If I understand the code correctly, it avoids the endless looping error I
    was stumbling over because it only goes through the string one time, a
    search chunk at a time.

    Nice solution.

    BTW, Dale Fugier also sent me a note on this subject mentioning DOSLib's
    dos_strreplace function - which also works for this task. (Thanks to you
    also, Dale!)

    So it appears I have been provided with an abundance of assistance for this.

    Best regards,
    David Kozina
     
    David Kozina, Jul 28, 2004
    #6
  7. David Kozina

    kozmos Guest

    Using vl-string-search and vl-string-subst will be a fast way in replace characters within a string as codes:
    (defun q-string-subst (new old string)
    (while (vl-string-search old string)
    (setq string (vl-string-subst new old string))
    )
    string
    )

    But we must face a situation of that the new string contain the whole old string that need to be replaced (such as replace “ABCSS†<New> with “ABC†<Old>), in such a situation, we must use an intermediate string to substitute with in order to avoid un-end looping vl-string-search old string in the whole string.
    The code below will avoid this and run proper for all situations in string substitution:

    (defun q-string-subst (new old string / tmp)
    (setq tmp "q-string-subst")
    (while (vl-string-search old string)
    (setq string (vl-string-subst tmp old string))
    )
    (while (vl-string-search tmp string)
    (setq string (vl-string-subst new tmp string))
    )
    string
    )
     
    kozmos, Jul 28, 2004
    #7
  8. You did say substitute, not remove. Sorry.

    PS: I'll make the changes to the comments.
     
    Jason Piercey, Jul 28, 2004
    #8
  9. I have, and still use, a routine called CHTEXT that I think was probably a
    download from Cadalyst or Cadence magazine years ago. It does exactly what
    you want with its "global" text-substitution option (along with lots of
    other things it can CHange about TEXT). But it dates from pre-Mtext days,
    and doesn't work with that, only with regular (plain) text entities.

    Kent Cooper, AIA
     
    Kent Cooper, AIA, Jul 28, 2004
    #9
  10. David Kozina

    David Kozina Guest

    Kozmos (nice name!) ;)

    Thanks. However, I must say I found your routine's logic a bit confusing -
    especially that (setq tmp "q-string-subst") part.

    It finally dawned on me that what you're doing is making a preliminary
    substitution (with what you would hope is a totally bogus string), then
    replace THAT with the desired string. That's a sneaky way to do it, I gotta
    admit. I'm not too sure if sneaky = good in this case, because you are in
    any case making an assumption about what the user ISN'T going to try to do.

    John Uhden's routine seemed to me to be easier to follow - but I found I
    could still generate a stack overflow error with:

    (@cv_strsubst_all "B" "" "ILLY")

    Since (vl-string-subst "B" "" "ILLY") -> "BILLY"
    I thought it might be good to emulate this for one iteration only, so I
    modified John's routine slightly:

    Code:
    
    ; Like vl-string-subst but replace ALL instances in a string
    ; Copyright 2000 by John Uhden
    ; Modified by David Kozina
    (defun juStringSubstAll
    (NewPatt_str ; New Substring
    OldPatt_str ; Substring to be replaced by New
    Process_str ; String to modify
    /
    NewPattLength ; length of New Substring (chunk)
    StartPosition ; current processing position
    )
    (setq StartPosition 0)
    (cond
    ((eq OldPatt_str "")
    (vl-string-subst NewPatt_str OldPatt_str Process_str StartPosition)
    );_end case
    (T
    (setq NewPattLength (strlen NewPatt_str))
    (while
    (setq StartPosition
    (vl-string-search OldPatt_str Process_str StartPosition)
    );_end setq
    (setq Process_str
    (vl-string-subst NewPatt_str OldPatt_str Process_str StartPosition)
    );_end setq
    (setq StartPosition (+ StartPosition NewPattLength))
    );_end while
    Process_str
    );_end case
    );_end cond
    );_end defun
    
    

    characters within a string as codes:
    string that need to be replaced (such as replace “ABCSS†<New> with
    “ABC†<Old>), in such a situation, we must use an intermediate string to
    substitute with in order to avoid un-end looping vl-string-search old string
    in the whole string.
     
    David Kozina, Jul 28, 2004
    #10
  11. David Kozina

    David Kozina Guest

    Kent,

    I remember CHTEXT and I think I still have a copy somewhere.

    Basically, as Jason implied, I was looking more for a 'toolbox' function
    than an all-in-one do-all program - less overhead.

    Thanks for mentioning it, though.

    Best regards,
    David Kozina
     
    David Kozina, Jul 28, 2004
    #11
  12. If you do still have CHTEXT, and don't need to do this in Mtext entities,
    you could make a "toolbox" menu item that said:

    [ReplaceString]^C^CCHTEXT ALL ;T ;

    and it would leave you at the point where it's asking you for the string you
    want to replace, and then what you want to replace it with. It would then
    do that in all occurrences in Text entities, at least in the current space.

    Kent Cooper, AIA


    ...
     
    Kent Cooper, AIA, Jul 28, 2004
    #12
  13. Kent,

    I don't think this was really a question about entities
    that contain strings, rather strings themselves regardless
    of where they originate from. Could be that the strings
    in question come from text, mtext, attdefs, read from
    a file, etc....

    A toolbox function that handles string substitution could
    be used in any of the above circumstances.
     
    Jason Piercey, Jul 28, 2004
    #13
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.