string
title: String sidebar_position: 5
String
Part of the function and operator catalog. Every example shown below is
executed as an assertion by the engine's own test suite (examples.test.ts), so a result shown
here is a result the engine actually produces for that input.
UPPER
UPPER(text: text) -> text
Converts text to upper case using locale-independent case mapping only — the result never changes with the host's locale, and no locale-sensitive case rule (such as Turkish dotless i) is ever applied.
Examples:
UPPER('abc')- result:
"ABC"
- result:
UPPER('i')- result:
"I"
- result:
LOWER
LOWER(text: text) -> text
Converts text to lower case using locale-independent case mapping only — the result never changes with the host's locale.
Examples:
LOWER('ABC')- result:
"abc"
- result:
LOWER('I')- result:
"i"
- result:
TRIM
TRIM(text: text) -> text
Removes leading and trailing whitespace and line terminators. Interior whitespace is left untouched.
Examples:
TRIM(' a b ')- result:
"a b"
- result:
SUBSTRING
SUBSTRING(text: text, start: a number, length: a number) -> text
Returns a slice of text: a zero-based start position (in UTF-16 code units) and a length. A negative start counts from the end, consistent with array access. Reaching past the end of the text is an error, not a clamp — bound the call with LENGTH rather than relying on a clamp.
Examples:
SUBSTRING('abcdef', 0, 3)- result:
"abc"
- result:
SUBSTRING('abcdef', 2, 5)- fails with
EXPR_STRING_INDEX_OUT_OF_RANGE
- fails with
SUBSTRING('abcdef', -3, 3)- result:
"def"
- result:
SUBSTRING('abcdef', -10, 1)- fails with
EXPR_STRING_INDEX_OUT_OF_RANGE
- fails with
SUBSTRING('abc', LENGTH('abc'), 0)- result:
""
- result:
SPLIT
SPLIT(text: text, separator: text) -> an array of text
Splits text on a literal separator, returning an array of the pieces between occurrences. The empty text yields a one-element array containing the empty string; two consecutive separators yield an empty element between them. An empty separator is an error — a character-by-character split is a deliberate absence, not an accident.
Examples:
SPLIT('a,b,c', ',')- result:
["a","b","c"]
- result:
SPLIT('', ',')- result:
[""]
- result:
SPLIT('a,,b', ',')- result:
["a","","b"]
- result:
SPLIT('abc', '')- fails with
EXPR_TYPE_MISMATCH
- fails with
REPLACE
REPLACE(text: text, search: text, replacement: text) -> text
Replaces every occurrence of a literal piece of text with another — not only the first occurrence, which is the host language's own default and is deliberately not inherited here. The search text is always literal, never a pattern. An empty search text is an error.
Examples:
REPLACE('a-a-a', 'a', 'b')- result:
"b-b-b"
- result:
REPLACE('a.b.c', '.', 'X')- result:
"aXbXc"
- result:
REPLACE('abc', '', 'X')- fails with
EXPR_TYPE_MISMATCH
- fails with
CONCAT
CONCAT(first: text, second: text, ...) -> text
Joins two or more pieces of text together, in order. This is the only way to join text in rule-line: '+' is numeric only, and no argument is ever converted to text on the engine's own initiative — join a number or a date by converting it explicitly first.
Examples:
CONCAT('a', 'b')- result:
"ab"
- result:
CONCAT('a', 'b', 'c')- result:
"abc"
- result:
CONCAT('', '')- result:
""
- result:
CONCAT('a', 1)- fails with
EXPR_TYPE_MISMATCH
- fails with
INDEXOF
INDEXOF(text: text, search: text) -> a number
Returns the position (in UTF-16 code units) of the first occurrence of a piece of text, or minus one if it does not occur. Compare the result against minus one before using it as a position — an author guards on the result, rather than the call failing, because INDEXOF is a probe, not a lookup (unlike GET/FIND_BY). See IF's entry for the executable guard idiom.
Examples:
INDEXOF('abcabc', 'b')- result:
"1"
- result:
INDEXOF('abc', 'z')- result:
"-1"
- result:
INDEXOF('abc', '')- result:
"0"
- result:
LASTINDEXOF
LASTINDEXOF(text: text, search: text) -> a number
Returns the position (in UTF-16 code units) of the last occurrence of a piece of text, or minus one if it does not occur. Compare the result against minus one before using it as a position, exactly as INDEXOF's entry describes.
Examples:
LASTINDEXOF('abcabc', 'b')- result:
"4"
- result:
LASTINDEXOF('abc', 'z')- result:
"-1"
- result:
PADSTART
PADSTART(text: text, targetLength: a number, padText: text) -> text
Pads text on the left with a repeated pad text until it reaches a target length (in UTF-16 code units). If the text is already at or beyond the target length, it is returned unchanged and never truncated. The pad text's last repetition is truncated to land exactly on the target. An empty pad text is an error.
Examples:
PADSTART('7', 3, '0')- result:
"007"
- result:
PADSTART('abc', 2, '0')- result:
"abc"
- result:
PADSTART('1', 5, 'ab')- result:
"abab1"
- result:
PADSTART('a', 3, '')- fails with
EXPR_TYPE_MISMATCH
- fails with
PADEND
PADEND(text: text, targetLength: a number, padText: text) -> text
Pads text on the right with a repeated pad text until it reaches a target length (in UTF-16 code units). If the text is already at or beyond the target length, it is returned unchanged and never truncated. The pad text's last repetition is truncated to land exactly on the target. An empty pad text is an error.
Examples:
PADEND('7', 3, '0')- result:
"700"
- result:
PADEND('abc', 2, '0')- result:
"abc"
- result:
PADEND('1', 5, 'ab')- result:
"1abab"
- result:
PADEND('a', 3, '')- fails with
EXPR_TYPE_MISMATCH
- fails with
REPEAT
REPEAT(text: text, count: a number) -> text
Repeats a piece of text a whole number of times. A count of zero yields the empty string; a negative or fractional count is an error; a result longer than rule-line allows fails before anything is built.
Examples:
REPEAT('ab', 3)- result:
"ababab"
- result:
REPEAT('ab', 0)- result:
""
- result:
REPEAT('ab', -1)- fails with
EXPR_TYPE_MISMATCH
- fails with