DAY 032: _INSTRREV
#1
_INSTRREV is an INSTR function, but in reverse! Instead of searching left to right, it searches from right to left.

SYNTAX _INSTRREV(seed%, string$, search$)

Where:

seed% is starting point in the string to begin the search.
string$ is the string to be searched.
search$ is the search term.

Note: The first parameter, seed%, is optional. We can also code it as: _INSTRREV(string$, search$)

Use: Parsing function.

So if we can already search a string forward with INSTR(), what's the benefit of using _INSTRREV()?

Glad you asked...

Let's say we have a page margin of 40 spaces wide. Here is our first string for that document...

a$ = "Pete and Steve walk into a bar. Steve blames Pete for not raising the bar higher."

Oops, that's longer than 40-characters? What do we do now Batman?

Well, simple "Stevey-boy" Wonder, we use the Bat-o-axe and chop it! (I have an old bat-o-axe around the house... Ouch! Hit by the bat-pan again!)

Well while I recover from being being badly bat-tered, let's take a short commercial break and see INSTR() vs  _INSTRREV() in action.

Code: (Select All)
WIDTH 82, 25
LOCATE 10, 1: PRINT " Okay, here is our string to chop to the page width of 40...              "
a$ = "Pete and Steve walk into a bar. Steve blames Pete for not raising the bar higher."
LOCATE 20, 1: PRINT a$; ''PRINT MID$(a$, 1, _WIDTH - 2): PRINT " "; MID$(a$, _WIDTH - 1)
mr = 40 ' Right margin limit
LOCATE 1, mr + 1: PRINT "|";
SLEEP
LOCATE 10, 1: PRINT "First we chopped the string to the page width: a$ = MID$(a$, 1, mr)                  "
a$ = MID$(a$, 1, mr)
LOCATE 1, 1
PRINT a$;
SLEEP
LOCATE 10, 1: PRINT "Okay, we need to get rid of the "; CHR$(34); "bl"; CHR$(34); " part of blames on our first line...    "
LOCATE 12, 1: PRINT "So let's try doing that with INSTR() with a nice long loop function..."; ""
SLEEP
LOCATE 10, 1: PRINT "Well that's working, but it's taking several parsing loops.                                                        "
LOCATE 12, 1: PRINT SPACE$(_WIDTH);
LOCATE 1, 1: PRINT SPACE$(mr);
LOCATE 1, 1
seed% = 0: j = 0
DO
    chop = j
    j = INSTR(seed%, a$, " ")
    COLOR 8: PRINT MID$(a$, seed%, j - seed% + 1);: _DELAY .66 ' For fun, we will time delay print each parse.
    seed% = j + 1 ' Move forward in our string - character past the last space.
LOOP UNTIL j = 0
COLOR 7
LOCATE 1, 1
PRINT MID$(a$, 1, chop);
SLEEP
LOCATE 10, 1: PRINT "Okay, let's do that with a 1-line _INSTRREV(): chop = _INSTRREV(a$, "; CHR$(34); " "; CHR$(34); ") "
LOCATE 1, 1: PRINT SPACE$(mr);
SLEEP 5
chop = _INSTRREV(a$, " ")
LOCATE 1, 1
PRINT MID$(a$, 1, chop);
LOCATE 10, 1: PRINT "Well that was easy!                                                                        "


Now the seed% part in _INSTRREV is used a bit differently than INSTR() in that it is read right to left, instead of left to right. So instead of stating your seed% at zero, you start it at the last space - 1 in your string to be chopped.

Code: (Select All)
a$ = "Pete and Steve walk into a bar. Steve bl"
LOCATE 1, 41: PRINT "|";
_DELAY 1
DO
    seed% = _INSTRREV(a$, " ") - 1: j = 0
    DO
        chop = j
        j = _INSTRREV(seed%, a$, " ")
        LOCATE , j + 1: PRINT MID$(a$, j + 1, seed% - j + 1);: _DELAY .5
        REM PRINT seed%, j
        seed% = j - 1 ' Move backwards in our string - character past the previous space.
    LOOP UNTIL j = 0
    LOCATE 1, 1: PRINT SPACE$(40);: _DELAY 1: LOCATE 1, 1
    seed% = 0: j = 0
    DO
        chop = j
        j = INSTR(seed%, a$ + " ", " ")
        PRINT MID$(a$, seed%, j - seed% + 1);: _DELAY .5 ' For fun, we will time delay print each parse.
        seed% = j + 1 ' Move forward in our string - character past the last space.
    LOOP UNTIL j = 0
    LOCATE 1, 1: PRINT SPACE$(40);: _DELAY 1: LOCATE 1, 1
LOOP

Well one practical application I wish we could do with this keyword is seed it find a term in a list of terms, separated with a delimiter. Well, we can build a function and use our key INSTRREV() and I'll throw in _INSTR() for no extra charge.

First input if you are searching forwards or backwards and then input the what number term to find, 1 - 10.

Code: (Select All)
DO
    DO
        CLS
        a$ = "dog cat rabbit cow mule pig elephant tiger bear Steve"
        PRINT a$: PRINT
        INPUT "Pick From the Left [1] or the Right [-1]: ", tmp%: PRINT
        INPUT "From 1 - 10, What Term #", tnum%
        IF tnum% >= 1 AND tnum% <= 10 AND tmp% >= -1 AND tmp% <= 2 AND tmp% <> 0 THEN EXIT DO
    LOOP
    tnum% = tnum% * tmp%
    PRINT
    PRINT " You chose: "; parse(a$, tnum%)
    PRINT: PRINT "Press any key to continue or Esc to quit..."
    _KEYCLEAR
    SLEEP
    IF INKEY$ = CHR$(27) THEN SYSTEM
LOOP

FUNCTION parse$ (a$, tnum%)
    IF tnum% < 0 THEN
        seed% = _INSTRREV(a$ + " ", " ") - 1: j = 0
        FOR i = 1 TO ABS(tnum%)
            chop = j
            j = _INSTRREV(seed%, a$ + " ", " ")
            IF i <> ABS(tnum%) THEN seed% = j - 1
        NEXT
        parse$ = MID$(a$, j + 1, seed% - j + 1)
    ELSE
        seed% = 0: j = 0
        FOR i = 1 TO tnum%
            chop = j
            j = INSTR(seed%, a$ + " ", " ")
            IF i <> tnum% THEN seed% = j + 1
        NEXT
        parse$ = MID$(a$, seed%, j - seed% + 1)
    END IF
END FUNCTION

Other uses are parsing off a file path to show just the directory:

From the Wiki...

Code: (Select All)
fullPath$ = "C:\Documents and Settings\Administrator\Desktop\qb64\internal\c\libqb\os\win\libqb_1_2_000000000000.o"
file$ = MID$(fullPath$, _INSTRREV(fullPath$, "\") + 1)
PRINT file$


One last thing, which also applies to INSTR(). Both will return zero if the search term, or aka sub-string, isn't found. So if you are using it with mid$() be aware that zero will give you the full string in the output, instead of a null string. You will need to write a conditional statement to handle this behavior...

Code: (Select All)
a$ = "123456789" ' No space(s).
x$ = "" ' Make x$ a null string just in case x$ was assigned someplace else.
substring$ = " "
j = _INSTRREV(a$, substring$)
IF j THEN x$ = MID$(a$, j) ' Only change null x$ if j is non-zero.
PRINT "x$ = "; x$ ' Nothing will print here now that we put in the above condition.
SLEEP
PRINT: PRINT MID$(a$, _INSTRREV(a$, substring$)) ' This would have printed the whole string without the condition.

Tune in tomorrow. Same Bat time, same Bat channel.

Pete
Reply


Messages In This Thread
DAY 032: _INSTRREV - by Pete - 12-12-2022, 08:58 PM
RE: DAY 032: _INSTRREV - by vince - 12-12-2022, 09:10 PM
RE: DAY 032: _INSTRREV - by mnrvovrfc - 12-12-2022, 09:10 PM
RE: DAY 032: _INSTRREV - by vince - 12-12-2022, 09:39 PM
RE: DAY 032: _INSTRREV - by Pete - 12-12-2022, 10:20 PM
RE: DAY 032: _INSTRREV - by vince - 12-13-2022, 12:03 AM
RE: DAY 032: _INSTRREV - by Pete - 12-13-2022, 01:35 AM
RE: DAY 032: _INSTRREV - by vince - 12-13-2022, 02:02 AM
RE: DAY 032: _INSTRREV - by SMcNeill - 12-13-2022, 09:34 AM
RE: DAY 032: _INSTRREV - by mnrvovrfc - 12-13-2022, 11:16 AM
RE: DAY 032: _INSTRREV - by SMcNeill - 12-13-2022, 09:43 AM
RE: DAY 032: _INSTRREV - by Pete - 12-13-2022, 02:52 PM



Users browsing this thread: 10 Guest(s)