Skip to main content

Searching Strings

BBj has two string searching functions: POS() for literal substring matching and MASK() for regex pattern matching. POS() handles the vast majority of search tasks; MASK() is available when you need the full power of regular expressions.

POS() -- Find Substring Position

POS() searches for a substring and returns its 1-based position, or 0 if not found:

a$ = "MONTUEWEDTHUFRISATSUN"
print pos("WED" = a$)
rem Output: 7

print pos("XYZ" = a$)
rem Output: 0

Note the syntax: the search string comes before the = sign and the target string comes after. This reads as "find the position of WED in a$."

Searching from a Starting Position

Pass a second argument to start the search at a specific position:

a$ = "hello world hello"
print pos("hello" = a$, 7)
rem Output: 13

Use a negative value for the second argument to scan from the end of the string toward the beginning:

b$ = "hello world hello"
print pos("hello" = b$, -1)
rem Output: 13

This finds the last occurrence. The -1 means "start from the end, find the first match scanning backward."

Counting Occurrences

When the third argument is 0, POS() returns the count of non-overlapping occurrences instead of a position:

b$ = "hello world hello"
print pos("hello" = b$, 1, 0)
rem Output: 2

POS() Quick Reference

SyntaxMeaning
pos("find"=a$)First occurrence (position or 0)
pos("find"=a$, n)First occurrence at or after position n
pos("find"=a$, -1)Last occurrence (backward scan)
pos("find"=a$, 1, 0)Count of occurrences

MASK() -- Regex Pattern Matching

MASK() matches a string against a Perl 5 regular expression and returns the 1-based position of the match, or 0 if no match:

a$ = "config.bbj"
print mask(a$, ".*\.bbj")
rem Output: 1 (match found starting at position 1)

After a successful MASK() call, TCB(16) returns the length of the matched text:

a$ = "order-12345-draft"
if mask(a$, "[0-9]+") then print "Match length: ", tcb(16)

Common Regex Patterns

PatternMatches
[0-9]+One or more digits
[A-Za-z]+One or more letters
^[A-Z]Starts with uppercase letter
\.bbj$Ends with .bbj
\s+One or more whitespace characters

Since MASK() uses standard Perl 5 syntax, any regex reference applies. If you already know regex from Java, Python, or JavaScript, the same patterns work here.

POS() vs. MASK() -- When to Use Each

ScenarioUseWhy
Find a known substringPOS()Simpler, faster
Count occurrencesPOS()Built-in with third argument
Scan backwardPOS()Built-in with negative second argument
Match a pattern (digits, email, etc.)MASK()Regex required
Validate formatMASK()Regex handles complex rules
Simple presence checkPOS()if pos("x"=a$) then ...

Rule of thumb: Use POS() unless you need pattern matching. It is simpler to read and covers most search tasks.

Reading Legacy Code

See Reading Legacy Code for pre-MASK() string searching patterns and other historical approaches.

Further Reading