|
<< Click to Display Table of Contents >> Navigation: 3. Script Language > String commands > !STR.- String Command > Instring - Find Commands > String Operations |
MiniRobotLanguage (MRL)
STR.Find
Find a Text/String inside of a Text/String

All Tests passed.
Intention
This command searches for a string (P3) inside another string (P1), starting from a specified position (P2).
The result (1-based position or 0 if not found) is placed on the Top of Stack (TOS) or in an optional variable (P4).
The search is case-sensitive (e.g., "AB" != "ab"). If P2 is positive (or 0, defaults to 1), searches left-to-right from that position. If negative (e.g., -1), searches right-to-left from the end (or |P2| bytes from end), but result is always absolute 1-based position from start.
This command is useful for locating substrings in text processing, parsing, or binary data handling without altering the original.
The command is binary-safe for both P1 and P3, with variables resolved only once to prevent unwanted expansion of special folders or system variables.
Schematic (Forward and Reverse Search)
Source: "12345AB6789"
Find: "AB" Start=1 (LTR) --> Pos=6
Search --> |1|2|3|4|5|A|B|6|7|8|9|
^ (Found at 6)
Find: "AB" Start=-1 (RTL) --> Pos=6 (searches from end, finds last "AB")
Search <-- |9|8|7|6|B|A|5|4|3|2|1|
^ (Absolute pos 6)
Syntax
STR.Find|P1|P2|P3[|P4]
Parameter Explanation
•P1 - (Source String) The string to search within. Binary-compatible variable resolution; no special folders/system vars expanded to preserve binary data.
•P2 - (Optional Start Position) Numeric, fully resolved. Positive/0: LTR from pos (1 if 0); Negative: RTL from end or |P2| bytes from end.
•P3 - (Find String) The substring to search for. Binary-compatible variable resolution.
•P4 - (Optional Result Variable) Variable for result (position or 0). If omitted, pushed to TOS.
Examples
' Basic forward search (from original sample)
$$SRC=12345AB6789
$$FND=AB
STR.Find|$$SRC|1|$$FND
$$POS=$tos$
' $$POS = 6
' Reverse search from end (from original sample)
$$SRC=12345AB67AB89
$$FND=AB
STR.Find|$$SRC|-1|$$FND
$$POS=$tos$
' $$POS = 10 (last "AB" from end)
' Case sensitivity: No match
$$SRC=12345ab6789
$$FND=AB
STR.Find|$$SRC|1|$$FND|$$POS
' $$POS = 0 (case mismatch)
' Negative start: From 2nd byte from end
$$SRC=AB12AB34AB
$$FND=AB
STR.Find|$$SRC|-2|$$FND|$$POS
' $$POS = 7 (searches RTL from len-1, finds "AB" at 7)
'-------------------------------------------------------------
' =================================================================
' SELF-VALIDATING TEST SCRIPT for STR.Find (Find Substring)
' Purpose: Verify forward/reverse search, start positions, case sensitivity,
' and edge cases. Case-sensitive only.
' Stack: Pushes 1 item: TOS = position (1-based from start, 0 if not found).
' Uses short jumps (JIV.) and clear PRT. for readability.
' =================================================================
' Initialize counters
$$PAS=0
$$FAI=0
STS.CLEAR
PRT. ===================================================
PRT. 1. FORWARD SEARCH TESTS (P2 >= 0)
PRT. ===================================================
PRT. Test 1.1: Basic forward search (P2=1)
$$SRC=12345AB6789
$$FND=AB
STR.Find|$$SRC|1|$$FND
$$EXP=6
JIV.$tos$!$$EXP|Lab_Error1
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next1
:Lab_Error1
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next1
STS.CLEAR
PRT. Test 1.2: Forward search with P2=0 (defaults to 1)
$$SRC=12345AB6789
$$FND=AB
STR.Find|$$SRC|0|$$FND
$$EXP=6
JIV.$tos$!$$EXP|Lab_Error2
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next2
:Lab_Error2
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next2
STS.CLEAR
PRT. Test 1.3: Forward search starting after match (P2=7)
$$SRC=12345AB6789
$$FND=AB
STR.Find|$$SRC|7|$$FND
$$EXP=0
JIV.$tos$!$$EXP|Lab_Error3
PRT. -> PASS (no match after position 7)
VIC.$$PAS
JMP.Lab_Next3
:Lab_Error3
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next3
STS.CLEAR
PRT. Test 1.4: Match at very start
$$SRC=AB12345
STR.Find|$$SRC|1|AB
$$EXP=1
JIV.$tos$!$$EXP|Lab_Error4
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next4
:Lab_Error4
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next4
STS.CLEAR
PRT. ===================================================
PRT. 2. REVERSE SEARCH TESTS (P2 < 0)
PRT. ===================================================
PRT. Test 2.1: Reverse from end (P2=-1)
$$SRC=12345AB67AB89
$$FND=AB
STR.Find|$$SRC|-1|$$FND
$$EXP=10
JIV.$tos$!$$EXP|Lab_Error5
PRT. -> PASS (last "AB" at 10)
VIC.$$PAS
JMP.Lab_Next5
:Lab_Error5
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next5
STS.CLEAR
PRT. Test 2.2: Reverse from 2nd byte from end (P2=-2)
$$SRC=12345AB67AB89
$$FND=AB
STR.Find|$$SRC|-2|$$FND
$$EXP=10
JIV.$tos$!$$EXP|Lab_Error6
PRT. -> PASS (still finds last "AB")
VIC.$$PAS
JMP.Lab_Next6
:Lab_Error6
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next6
STS.CLEAR
PRT. Test 2.3: Reverse from 5th byte from end (P2=-5)
$$SRC=12345AB67AB89
$$FND=AB
STR.Find|$$SRC|-5|$$FND
$$EXP=6
JIV.$tos$!$$EXP|Lab_Error7
PRT. -> PASS (finds first "AB" when scanning from position 10)
VIC.$$PAS
JMP.Lab_Next7
:Lab_Error7
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next7
STS.CLEAR
PRT. Test 2.4: Reverse search with no match
$$SRC=12345AB67AB89
$$FND=XYZ
STR.Find|$$SRC|-1|$$FND
$$EXP=0
JIV.$tos$!$$EXP|Lab_Error8
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next8
:Lab_Error8
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next8
STS.CLEAR
PRT. ===================================================
PRT. 3. CASE SENSITIVITY TESTS
PRT. ===================================================
PRT. Test 3.1: Case mismatch (forward)
$$SRC=12345ab6789
$$FND=AB
STR.Find|$$SRC|1|$$FND
$$EXP=0
JIV.$tos$!$$EXP|Lab_Error9
PRT. -> PASS (case-sensitive)
VIC.$$PAS
JMP.Lab_Next9
:Lab_Error9
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next9
STS.CLEAR
PRT. Test 3.2: Case mismatch (reverse)
$$SRC=12345ab6789
$$FND=AB
STR.Find|$$SRC|-1|$$FND
$$EXP=0
JIV.$tos$!$$EXP|Lab_Error10
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next10
:Lab_Error10
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next10
STS.CLEAR
PRT. ===================================================
PRT. 4. EDGE CASE TESTS
PRT. ===================================================
PRT. Test 4.1: Empty source string
$$SRC=
$$FND=test
STR.Find|$$SRC|1|$$FND
$$EXP=0
JIV.$tos$!$$EXP|Lab_Error11
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next11
:Lab_Error11
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next11
STS.CLEAR
PRT. Test 4.2: Empty find string
$$SRC=Hello
$$FND=
STR.Find|$$SRC|1|$$FND
$$EXP=0
JIV.$tos$!$$EXP|Lab_Error12
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next12
:Lab_Error12
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next12
STS.CLEAR
PRT. Test 4.3: Find string longer than source
$$SRC=Hi
$$FND=Hello
STR.Find|$$SRC|1|$$FND
$$EXP=0
JIV.$tos$!$$EXP|Lab_Error13
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next13
:Lab_Error13
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next13
STS.CLEAR
PRT. Test 4.4: Match at very end
$$SRC=EndsWithAB
$$FND=AB
STR.Find|$$SRC|1|$$FND
$$EXP=9
JIV.$tos$!$$EXP|Lab_Error14
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next14
:Lab_Error14
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next14
STS.CLEAR
PRT. Test 4.5: Binary-safe test (null bytes)
$$SRC=AB$chr(0)$CD
$$FND=$chr(0)$CD
STR.Find|$$SRC|1|$$FND
$$EXP=3
JIV.$tos$!$$EXP|Lab_Error15
PRT. -> PASS (binary-safe)
VIC.$$PAS
JMP.Lab_Next15
:Lab_Error15
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next15
STS.CLEAR
PRT. ===================================================
PRT. 5. BOUNDARY & SPECIAL CASES
PRT. ===================================================
PRT. Test 5.1: P2 beyond string length (forward)
$$SRC=Hello
$$FND=o
STR.Find|$$SRC|10|$$FND
$$EXP=0
JIV.$tos$!$$EXP|Lab_Error16
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next16
:Lab_Error16
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next16
STS.CLEAR
PRT. Test 5.2: P2 beyond string length (reverse)
$$SRC=Hello
$$FND=H
STR.Find|$$SRC|-10|$$FND
$$EXP=0
JIV.$tos$!$$EXP|Lab_Error17
PRT. -> PASS (INSTR returns 0 if position beyond string)
VIC.$$PAS
JMP.Lab_Next17
:Lab_Error17
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next17
STS.CLEAR
PRT. Test 5.3: Single character search (forward)
$$SRC=abcdef
$$FND=d
STR.Find|$$SRC|1|$$FND
$$EXP=4
JIV.$tos$!$$EXP|Lab_Error18
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next18
:Lab_Error18
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next18
STS.CLEAR
PRT. Test 5.4: Single character search (reverse)
$$SRC=abcdef
$$FND=d
STR.Find|$$SRC|-1|$$FND
$$EXP=4
JIV.$tos$!$$EXP|Lab_Error19
PRT. -> PASS
VIC.$$PAS
JMP.Lab_Next19
:Lab_Error19
$$MSG= -> FAIL - Result: $tos$ (exp: $$EXP)
PRT.$$MSG
VIC.$$FAI
:Lab_Next19
STS.CLEAR
PRT. ===================================================
PRT. TEST SUMMARY
PRT. ===================================================
CAL.$$TOT=$$PAS+$$FAI
$$MSG=Total Tests: $$TOT
PRT.$$MSG
$$MSG=Passed: $$PAS
PRT.$$MSG
$$MSG=Failed: $$FAI
PRT.$$MSG
' Display final result
JIV.$$FAI=0|Lab_Success
$$MSG=FAILURE: $$FAI of $$TOT tests failed.
MBX.$$MSG|Test Result|16
JMP.Lab_End
:Lab_Success
MBX.SUCCESS: All tests passed!|Test Result|64
:Lab_End
ENR.
Remarks
-Case-sensitive search; use VTU./VTL. for insensitive.
-Variables in P1/P3 resolved once (binary-safe; no special/system vars expanded).
-P2=0 defaults to 1 (LTR start).
-Negative P2: RTL from end or |P2| from end; result always absolute from start.
-If P2 is beyond string length (positive or negative), returns 0.
-If find longer than remaining string, returns 0.
-For replacement, use RPL.; for extraction, GSS./GES./SBD.
Limitations
-Case-sensitive only; no insensitive flag.
-No wildcard/regex; for patterns, use STR.Find with advanced modes or loops.
-Binary-safe but no overlap handling; finds first non-overlapping occurrence.
See also:
SBD. - String between Delimiter