Qu

substr

Builtin index · Collections & strings

result = substr(s, start, [length])

Input: s, start, length · Output: result

What it is

s is a Str; start (number, 0-based character index, must lie in [0, char_count]) is where the slice begins; optional length (number of characters, default: to the end) is clamped rather than erroring if it runs past what's left. Plain aliases of the same implementation (mid exists purely for BASIC/Excel discoverability).

Overloads

2 forms. Each carries its own inputs, outputs and worked example — pick the tab for the one you are calling.

CodeInputOutputDescription
result = substr(s, start)
s Strs is a Str.
start numberstart (number, 0-based character index, must lie in [0, char_count]) is where the slice begins.
result Str
Everything from start to the end of s — the 2-argument form.

Examples

From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.

s = "Hello, World!"
print(substr(s, 7))          # "World!" — to the end

print(substr(s, 0, 5))       # "Hello" — bounded

print(substr(s, 7, 100))     # "World!" — clamped, not an error

print(mid(s, 7, 5))          # "World" — mid is substr under another name

output
World!
Hello
World!
World

from collections-strings

print("-" * 40)                                  # "----------------------------------------"

print("hello".substr(0, 2).replace("e", "i"))    # "hi"

print(pad_left(str(7), 3, "0"))                  # "007"

print(proper("ada lovelace"))                    # "Ada Lovelace"

print(count("banana", "a"))                      # 3

output
----------------------------------------
hi
007
Ada Lovelace
3

from collections-strings

s = "  Hello, Qu World!  "
trimmed = trim(s)
parts = split(trimmed, ", ")
print(parts)                  # ["Hello", "Qu World!"]

print(upper(parts[0]))        # HELLO

print(starts_with(trimmed, "Hello"))  # true

print("hello".substr(0, 2).replace("e", "i").flip().flip())
print("hi world".split(" ").join(", ") + "!")
output
("Hello", "Qu World!")
HELLO
true
hi
hi, world!

from collections-strings

CodeInputOutputDescription
result = substr(s, start, length)
s Strs is a Str.
start numberstart (number, 0-based character index, must lie in [0, char_count]) is where the slice begins.
length numberoptional length (number of characters, default: to the end) is clamped rather than erroring if it runs past what's left.
result Str
Exactly length characters starting at start, clamped (not an error) if length runs past what's left — the 3-argument form.

Examples

From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.

s = "Hello, World!"
print(substr(s, 7))          # "World!" — to the end

print(substr(s, 0, 5))       # "Hello" — bounded

print(substr(s, 7, 100))     # "World!" — clamped, not an error

print(mid(s, 7, 5))          # "World" — mid is substr under another name

output
World!
Hello
World!
World

from collections-strings

How it works

All index/length arguments below are 0-based (matching every other index in this codebase) and unicode-aware: built on .chars(), never a raw byte slice, so a multi-byte UTF-8 string indexes by character, not by byte (a naive byte slice would panic or corrupt on non-ASCII input). substr(s, start[, length]) / mid(s, start, length) — plain aliases of the same implementation: MATLAB has no mid at all (that's a BASIC/Excel convention), and since Qu already indexes 0-based everywhere (unlike BASIC/Excel's 1-based MID$), there is no real semantic difference to preserve — mid exists purely for discoverability by BASIC/Excel habit. start must be within [0, char_count] (== char_count is the valid "nothing left" case, matching the empty-slice-at-the-end convention s[n:] uses elsewhere); length is clamped to whatever is actually available rather than erroring — asking for more than what's left (substr(s, 0, 1000) to mean "the rest") is a common, harmless overshoot, unlike a genuinely out-of-range start.

From the note above this builtin in the interpreter, where the reasoning was written down as it was built.

See also

mid — documented in the same entry.