Announcement

Collapse
No announcement yet.

Extract, Replace, Extract/Replace Only Particular?

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

  • Extract, Replace, Extract/Replace Only Particular?

    I find myself in a situation that before I go ahead and "Just Do It" myself, are there functions that Extract, or Replace only certain occurrences of a matching string?

    Reason I ask is say for simplicity, In this example I will say Replace (I will worry about Extract etc later, I just need to know if what I am about to write is reinventing the wheel or not)

    Example: "blackcat, white cat ,blue cat, what is a cat?, yadda yadda"
    Command to execute: Remove second occurrence of the word "cat"
    Resulting string: "blackcat, white < The word CAT deleted from here >,blue cat, what is a cat?, yadda yadda"

    I know it can easily be done, but just wondered if its already done? or worthwhile writing a wrapper for?
    Engineer's Motto: If it aint broke take it apart and fix it

    "If at 1st you don't succeed... call it version 1.0"

    "Half of Programming is coding"....."The other 90% is DEBUGGING"

    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

  • #2
    Yes, there are functions Remove, Replace, and extract (in addition to the classic MID$, etc).

    In fact there's a whole passel of functions that you can use. Probably you'll have to INSTR to find the specific occurrance you're looking for, but then replace or remove will do the job.
    John,
    --------------------------------
    John Strasser
    Phone: 480 - 273 - 8798

    Comment


    • #3
      Yeah, I'd do some more testing, but here's an idea:

      Code:
      #COMPILE EXE
      #DIM ALL
               'qReplace optimistically stands for quickReplace. Umm, okay.
      FUNCTION qReplace(origS AS STRING, fs AS STRING, cnt AS LONG, rs AS STRING) AS STRING
         LOCAL pos1, pos2, tCnt AS LONG
         pos2 = 1
      
         DO
            pos1 = INSTR(pos2, origS, fs)
            IF pos1 > 0 THEN         'is there a match?
               INCR tCnt             'is it the match # we want?
               IF tCnt = cnt THEN
                  FUNCTION = LEFT$(origS, pos1 - 1) & rs & MID$(origS, pos1 + LEN(fs))
                  EXIT FUNCTION
               END IF
            END IF
            pos2 = pos1 + 1
            IF pos1 = 0 THEN         'no match or went beyond str len
               FUNCTION = origS
               EXIT FUNCTION
            END IF
         LOOP
      
      END FUNCTION
      
      FUNCTION PBMAIN () AS LONG
          LOCAL xs AS STRING, ii AS LONG
      
          xs = "blackcat, white cat ,blue cat, what is a cat?,ackcat, white cat ,blue cat, what is a cat?, yadda yadda"
      
          FOR ii = 1 TO 11
             ? qReplace(xs, "cat", ii, "")       'replace with ""
             ? qReplace(xs, "cat", ii, "dog")    'replace with "dog"
          NEXT
      
      END FUNCTION
      Last edited by John Gleason; 14 Apr 2008, 08:58 PM. Reason: added some comments

      Comment


      • #4
        oops!
        Last edited by Chris Holbrook; 15 Apr 2008, 06:24 AM. Reason: unescessary

        Comment


        • #5
          I noticed you can make the function above into a single IF-THEN-ELSE. Also you may want to return an empty string on no match rather than a copy.

          Code:
             DO
                pos1 = INSTR(pos2, origS, fs)
                IF pos1 > 0 THEN
                   INCR tCnt
                   IF tCnt = cnt THEN
                      FUNCTION = LEFT$(origS, pos1 - 1) & rs & MID$(origS, pos1 + LEN(fs))
                      EXIT FUNCTION
                   END IF
                ELSE
                   FUNCTION = origS    'You could also say FUNCTION = "" and get an empty string if there is no match.
                   EXIT FUNCTION
                END IF
                pos2 = pos1 + 1
             LOOP

          Comment


          • #6
            Well, you can surely write this easily enough as shown above. (or with regular expressions).

            But if you really think it's a valuable suggestion, why don't you send in a new feature suggestion asking for an enhancement to INSTR?
            Code:
             iPos = INSTR ([startpos&], lookin, lookfor [,OCCUR occurNo&])
            Something like that, anyway. With the already optional first parameter, the syntax might get a little clumsy. Especially considering that if my own NFS for adding a case-insensitive option to INSTR is implemented there might be an even bigger fight for space in the parameter string.

            ???
            Code:
            iPos = INSTR ([startpos&], lookin, lookfor [,OCCUR occurNo&] [,UCASE])
            ????
            Michael Mattias
            Tal Systems Inc. (retired)
            Racine WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              I couldn't help but want to take a swing at this pitch...

              Code:
              FUNCTION fInstr(start AS LONG, s AS STRING, t AS STRING, nOccur AS LONG, repl AS STRING) AS STRING
                 LOCAL i, m, mm AS LONG
                 mm = MAX(start, 1)
                 FOR i = 1 TO nOccur
                    m = INSTR(mm, s, t): mm = m + LEN(t)
                 NEXT i
                 FUNCTION = LEFT$(s, m - 1) + repl + MID$(s, mm)
              END FUNCTION
              
              FUNCTION PBMAIN
                 LOCAL s, ss, t AS STRING
                 LOCAL m, mm, n, i AS LONG
                 s = "blackcat, white cat ,blue cat, what is a cat?, yadda yadda"
                 MSGBOX fInstr(0, s, "cat", 2, "dog") 
              END FUNCTION

              Comment


              • #8
                Charles, I haven't figured this out yet, but I get different results between our algos when the number of occurrences (nOccur in your function) exceeds the number present in the string, and even more perplexing, differences when used as in the example below:
                Code:
                FOR i = 1 TO 100
                     fInstr(0, s, "cat", i AND 3, "dog")
                     qReplace(s, "cat", i AND 3, "dog")    'replace with "dog"
                NEXT

                Comment


                • #9
                  In subject example "I and 3" will never equal anything but 0, 1, 2 or 3 (boolean AND).

                  Zero has GOT to be causing grief somewhere.

                  Unless "I and 3" is being evaluated as ((ISTRUE I) AND (ISTRUE 3)), in which case it will always equal -1 when I ranges from 1 to 100. I'll bet minus-one is even worse grief than would be zero.
                  Michael Mattias
                  Tal Systems Inc. (retired)
                  Racine WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    I'm afraid I wasn't very careful... STRIKE 1!
                    Here's another swing at the ball. Hopefully, it will be a base hit.

                    Code:
                    FUNCTION fInstr(start AS LONG, s AS STRING, t AS STRING, nOccur AS LONG, repl AS STRING) AS LONG
                       LOCAL i, m, mm AS LONG
                       mm = start
                       FOR i = 1 TO nOccur
                          m = INSTR(mm, s, t): IF m = 0 THEN EXIT FOR ELSE mm = m + LEN(t)
                          IF i = nOccur THEN s = LEFT$(s, m - 1) + repl + MID$(s, mm)
                       NEXT i
                       FUNCTION = m
                    END FUNCTION
                    
                    FUNCTION PBMAIN
                       LOCAL s, ss, t AS STRING, k AS LONG
                       LOCAL m, mm, n, i AS LONG
                       s = "blackcat, white cat ,blue cat, what is a cat?, yadda yadda"
                       k = fInstr(1, s, "cat", 2, "dog")
                       MSGBOX s 
                    END FUNCTION

                    Comment


                    • #11
                      I figured as much....I need to write wrappers to the simple Extract, and Replace functions...(No biggie, but thats why I asked to begin with so not to re-write the "Proverbial Wheel")

                      Nice to see the exchange of ideas though
                      Engineer's Motto: If it aint broke take it apart and fix it

                      "If at 1st you don't succeed... call it version 1.0"

                      "Half of Programming is coding"....."The other 90% is DEBUGGING"

                      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                      Comment


                      • #12
                        need to write wrappers to the simple Extract, and Replace functions
                        A Real Man would use a regular expression.

                        Actually the REGEXPR code you need for this is in the demo I posted at REGEXPR and REGREPL demo January 16, 2002

                        All ya gots to do is tap in to the REGEXPR/REGREPL loops shown to increment and test an integer occurrence number and exit when appropriate.

                        (Cliff, I only give you a hard time because I think you show promise and a little challenge might just bring it out).

                        MCM
                        Michael Mattias
                        Tal Systems Inc. (retired)
                        Racine WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment

                        Working...
                        X