|
<< Click to Display Table of Contents >> Navigation: 3. Script Language > String commands > !STR.- String Command > Instring - Find Commands > String Operations |
MiniRobotLanguage (MRL)
STR.CIContains
Checks for the Presence of Multiple Strings in a Source String (Case Insensitive)

On TOS you will find the parameter index that was matched (1-based). Below it, the 1-based position where it was found.
Intention
This command is used to check if one or more specified strings are contained within a source string.
The search is performed case-insensitively, meaning "Hello" will match "hello", "HELLO", or any mixed case variation (handled via internal UCASE conversion before INSTR).
It scans the source string from left to right, checking each search string in sequence (P2 first, then P3, etc.).
As soon as a match is found, it stops searching further parameters and pushes two values to the Top of stack:
1. The 1-based index of the matching parameter (TOS: e.g., 1 for P2, 2 for P3, up to 63 for P64).
2. The 1-based starting position in the source string where the match was found (below TOS).
If no match is found in any of the search strings, it pushes a single value: 0 (indicating no match).
This is particularly useful for conditional logic, such as validating input or routing based on keywords, without needing multiple separate checks. With support for up to 63 search strings, it handles complex multi-keyword validation efficiently. Note: No matched string is pushed to the stack; only index and position.
Syntax
STR.CIContains|P1|P2[|P3[|...[|P64]]]
Parameter Explanation
•P1 - (Source String) The main string in which to search for the specified strings. Can be a variable (e.g., $$SRC) or a literal string.
•P2 to P64 - (Search Strings) Up to 63 optional strings to check for their presence in P1. At least one (P2) must be specified. Can be variables (e.g., $$CH1) or literals. The search checks them in order: P2 first, then P3, etc., stopping at the first match.
Examples
' Basic example with multiple search strings (from original sample)
: $$SRC=<HelloWorld>
: $$CH1=Bello
: $$CH2=World
STR.CIContains|$$SRC|$$CH1|$$CH2
DMP.6
MBX. Stack (top to bottom): 1 (P2 index) | 2 (position in source)
ENR.
'--------------------------------------------------------------
' =================================================================
' SELF-VALIDATING TEST SCRIPT for STR.CIContains (Case-Insensitive Multi-String Contains)
' Purpose: Verify all features using IVV. for automated checks
' and a final summary report. Tests basic matches, multiple params, case-insens,
' no match, edge cases (empty strings, long search, max-like params).
' Stack: Always pushes 2 items: TOS=index (1-based param, 0 if no match),
' next=position (1-based char, 0 if no match).
' =================================================================
' --- Initialize Pass/Fail counters ---
$$PAS=0
$$FAI=0
STS.CLEAR
PRT. ===================================================
PRT. 1. BASIC SINGLE MATCH TEST
PRT. ===================================================
$$SRC=Hello World
$$SEA=hello
PRT. Test 1.1: Basic case-insensitive match (single param)...
STR.CIContains|$$SRC|$$SEA
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=1
IVV.$$IDX=$$EXP
$$EXP=1
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. ===================================================
PRT. 2. MULTIPLE PARAMS TEST (FIRST MATCH STOPS)
PRT. ===================================================
$$SRC=The Quick Brown Fox
$$S01=quick
$$S02=fox
$$S03=lazy
PRT. Test 2.1: Multiple params, match on P2 (first should be P2)...
STR.CIContains|$$SRC|NotFound|$$S01|$$S02|$$S03
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=2
IVV.$$IDX=$$EXP
$$EXP=5
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 2.2: Multiple params, no early match (hits P3)...
$$SRC=The Lazy Dog
STR.CIContains|$$SRC|NotHere|NotThere|lazy
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=3
IVV.$$IDX=$$EXP
$$EXP=5
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. ===================================================
PRT. 3. NO MATCH TEST
PRT. ===================================================
$$SRC=Hello World
PRT. Test 3.1: No match (single param)...
STR.CIContains|$$SRC|Zebra
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=0
IVV.$$IDX=$$EXP
$$EXP=0
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 3.2: No match (multiple params)...
STR.CIContains|$$SRC|Zebra|Elephant|Giraffe
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=0
IVV.$$IDX=$$EXP
$$EXP=0
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. ===================================================
PRT. 4. EDGE CASE TESTS
PRT. ===================================================
PRT. Test 4.1: Empty source string...
$$SRC=
STR.CIContains|$$SRC|hello
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=0
IVV.$$IDX=$$EXP
$$EXP=0
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 4.2: Empty search string (single)...
$$SRC=Hello World
STR.CIContains|$$SRC|
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=0
IVV.$$IDX=$$EXP
$$EXP=0
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 4.3: Search longer than source...
$$SRC=Hi
STR.CIContains|$$SRC|ThisIsVeryLongString
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=0
IVV.$$IDX=$$EXP
$$EXP=0
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 4.4: Multiple empty searches...
STR.CIContains|$$SRC|||
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=0
IVV.$$IDX=$$EXP
$$EXP=0
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 4.5: High param count (simulate max 63 with sample)...
' Note: Testing with 5 for brevity; in full, up to |P64
$$SRC=Match
STR.CIContains|$$SRC|not|here|but|this|match|extra|dummy|dummy2
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=5
IVV.$$IDX=$$EXP
$$EXP=1
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. ===================================================
PRT. 5. ADDITIONAL NORMAL TEST CASES
PRT. ===================================================
PRT. Test 5.1: Mixed case match (source uppercase, search lowercase)...
$$SRC=HELLO WORLD
$$SEA=hello
STR.CIContains|$$SRC|$$SEA
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=1
IVV.$$IDX=$$EXP
$$EXP=1
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 5.2: Literal search strings (no variables)...
$$SRC=PowerBASIC Rocks
STR.CIContains|$$SRC|power|basic|rocks|invalid
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=1
IVV.$$IDX=$$EXP
$$EXP=1
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 5.3: Match at end of string...
$$SRC=This is the end
STR.CIContains|$$SRC|middle|start|end
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=3
IVV.$$IDX=$$EXP
$$EXP=13
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 5.4: Partial word match (substring)...
$$SRC=Power Programming
STR.CIContains|$$SRC|powel|basic|prog
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=3
IVV.$$IDX=$$EXP
$$EXP=7
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 5.5: Duplicate search strings (first takes precedence)...
$$SRC=Duplicate Test
$$SEA=dup
STR.CIContains|$$SRC|dup|duplicate|dup
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=1
IVV.$$IDX=$$EXP
$$EXP=1
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
STS.CLEAR
PRT. Test 5.6: Match with spaces and punctuation...
$$SRC=->Hello, World!
STR.CIContains|$$SRC|hello|world|exclaim
$$TOS=#tos#
IVV.$$TOS=2
POV.$$IDX|$$POS
$$EXP=1
IVV.$$IDX=$$EXP
$$EXP=3
IVV.$$POS=$$EXP
PRT. -> PASS
VIC.$$PAS
ELS.
$$MSG= -> FAIL - Expected pos: $$EXP, Actual: $$POS
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected idx: $$EXP, Actual: $$IDX
PRT.$$MSG
VIC.$$FAI
EIF.
ELS.
$$MSG= -> FAIL - Expected stack size: 2, Actual: $$TOS
PRT.$$MSG
VIC.$$FAI
EIF.
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 message box ---
IVV.$$FAI=0
MBX.SUCCESS: All tests passed!|Test Result|64
ELS.
$$MSG=FAILURE: $$FAI of $$TOT tests failed.
MBX.$$MSG|Test Result|16
EIF.
ENR.
Remarks
-The search is always case-insensitive (via internal UCASE on source and searches before INSTR) and performed from left to right in the source string.
-It stops at the first match found among the search parameters, so order matters (earlier parameters take precedence).
-Stack pushes: Index (TOS, 1-based param number), Position (below, 1-based char position). No matched string is pushed.
-Supports up to 63 search strings (P2 to P64); the index on TOS will be 1 to 63 accordingly.
-Positions are 1-based (first character is 1). If the source is empty or search strings are empty, returns 0 (single push).
-For case-sensitive searches, consider using a custom macro with STR.Find or related commands.
Limitations
-Limited to 63 search strings; for more, use repeated calls or preprocessing with macros.
-Does not support wildcards or regex; for advanced patterns, use STR.Find with search patterns.
-Always case-insensitive; no flag for case-sensitive mode. Uses PowerBASIC INSTR after UCASE conversion.
See also: