Documentation/Reference

String library reference

On this page

Strings are valid UTF-8 independent values. Default parameters borrow without copying; results own their storage. Positions, lengths and padding widths below count Unicode scalar values, starting at zero. A combining sequence or emoji may contain several scalars. Equality and search are exact and case-sensitive. No implicit normalization, locale tailoring, or numeric conversion occurs.

Functions

All integer arguments/results use INTEGER (signed 64-bit). Fallible calls are checked automatically, including calls whose successful results are discarded; inline TRY is optional.

Function Result and behavior Declared error
LEN(text), ByteCount(text) Scalar count; UTF-8 byte count None
ByteAt(text, offset) Encoded byte at zero-based byte offset; invalid offset is fatal None
LEFT(text, count), RIGHT(text, count) At most count scalars from either end StringError
MID(text, start, count) At most count scalars starting at start; start may equal LEN StringError
INSTR(text, needle) First scalar position, or -1; empty needle gives 0 None
INSTRFROM(text, needle, start) First scalar position at/after start; empty needle gives start StringError
RINSTR(text, needle) Last scalar position, or -1; empty needle gives LEN None
CHR(value) One Unicode scalar encoded as UTF-8, including NUL StringError
ASC(text) First Unicode scalar’s integer value StringError
STR(value) Canonical integer or shortest round-tripping DOUBLE spelling, no leading space None
VAL(text) Strict signed decimal integer after Unicode whitespace trimming NumericError
SPACE(count), REPEAT(text, count) Repeated spaces or text; zero gives empty string StringError
UPPER(text), LOWER(text), CASEFOLD(text) Full Unicode 17 default mapping; may expand characters None
UCASE(text), LCASE(text) Aliases for UPPER and LOWER None
TRIM(text), LTRIM(text), RTRIM(text) Remove Unicode White_Space from both/start/end None
CONTAINS(text, needle) BOOLEAN substring test None
STARTSWITH(text, prefix), ENDSWITH(text, suffix) BOOLEAN boundary test None
REMOVEPREFIX(text, prefix), REMOVESUFFIX(text, suffix) Remove one matching boundary; otherwise return independent unchanged value None
REPLACE(text, old, replacement) Replace all nonoverlapping matches; empty old inserts at scalar boundaries, including both ends None
SPLIT(text, separator="") LIST OF STRING; empty separator splits Unicode code points, nonempty separators preserve empty fields StringError (legacy contract)
LINES(text) LIST OF STRING, splitting line boundaries without retaining separators None
JOIN(parts, separator) Join a LIST OF STRING None
PADLEFT(text, width), PADRIGHT(text, width) Space padding to width; shorter/negative widths leave text unchanged StringError
PADLEFTWITH(text, width, fill), PADRIGHTWITH(text, width, fill) Padding with exactly one scalar StringError
FORMAT(template, values) Replace {} with successive strings from LIST OF STRING; {{ and }} escape braces StringError
CODEPOINTS(text) LIST OF INTEGER containing Unicode scalar values None
UNICODEVERSION() “17.0.0” None

MID/INSTRFROM reject negative starts and starts beyond LEN. LEFT/RIGHT/MID reject negative counts; excessive nonnegative counts clamp to available text. SPACE/REPEAT reject negative counts. Padding widths and slicing positions are not display-column measurements.

VAL requires the entire trimmed input to be optional ASCII + or - followed by ASCII decimal digits. Empty input, embedded whitespace, fractional/exponent/radix notation, and trailing characters fail. The full signed 64-bit range is accepted. VAL parses INTEGER; STR also formats DOUBLE. Use checked CDBL(text) / VALDOUBLE(text) for floating-point parsing; see the math reference .

LINES recognizes CRLF as one boundary, plus LF, CR, vertical tab, form feed, U+001C–U+001E, NEL, line separator and paragraph separator. Empty input yields an empty list; a trailing line boundary does not add a final empty element. SPLIT with a nonempty separator preserves final empty fields. Its separator is optional and defaults to “”: omitted/empty separators split into Unicode code points, with empty input producing an empty list. Combining marks remain separate entries.

FORMAT requires exactly as many values as {} placeholders, and balanced/escaped braces. Values are strings: use STR explicitly for numeric values. Width/precision/type format specifications are deferred.

Traditional string-result spellings with a trailing dollar are optional call aliases, such as LEFT$(text, count), UCASE$(text) and STR$(value). They are recognized for the string-result functions listed above except UNICODEVERSION; they do not introduce typed variable suffixes or arbitrary dollar-named functions. INSTR/ASC/VAL/SPLIT/LINES return other types and have no dollar alias. This is modern BASIL behavior, not complete QuickBASIC compatibility: positions are zero-based, not-found is -1, CHR/ASC use Unicode scalars, and VAL is checked and strict.

Recoverable errors

NumericError and StringError are distinct built-in typed records with an INTEGER Code field. Construction is an ordinary value operation. User functions declare escaping types in FAILS, and RETURN ERROR explicitly forwards a caught error.

Error Code Meaning
NumericError 1 Invalid decimal integer syntax
NumericError 2 Integer outside the signed 64-bit range
StringError 1 Invalid Unicode scalar (negative, surrogate, or above U+10FFFF)
StringError 2 Invalid position or negative count
StringError 3 Reserved legacy split error code; empty separators now succeed
StringError 4 ASC called on empty text
StringError 5 Invalid template or mismatched format argument count
StringError 6 Padding fill is not exactly one scalar
StringError 7 Invalid byte sequence supplied to DecodeUtf8/ReadFileText
TRY
    PRINT UPPER("Straße")
    PRINT TRY LEFT("café 🌍", 4)
    PRINT JOIN(TRY SPLIT("one,two,three", ","), " | ")
    PRINT TRY VAL("42")
CATCH err AS StringError
    PRINT "String error code: " + STR(err.Code)
CATCH err AS NumericError
    PRINT "Number error code: " + STR(err.Code)
END TRY

Errors inside a catch target an outer matching catch or propagate from the function, never another clause of the same handler. Partial expressions and owned locals are cleaned on recoverable exit. Allocation failure remains fatal, separate from these errors, with no normal application-cleanup guarantee. Integer arithmetic overflow and invalid ByteAt access are also fatal.

From the BASIL documentation. View source ↗

Find your way around BASIL

Type to search the manual.