Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Function

Text.TrimStart, Text.TrimEnd, Text.PadStart, Text.PadEnd

Text.TrimStart(s[, chars]) / TrimEnd(s[, chars]) → string · Text.PadStart(s, width, pad) / PadEnd(s, width, pad) → string

Trim whitespace from one end of a string, or pad it out to a width with a fill string. Trimming uses the full Unicode whitespace set. Padding never truncates — a string already at or over the width comes back unchanged — and the fill is a STRING, cut to fit the gap exactly. All run in memory.

stable3 examples compiled by CIfunctiontextstdlib

Summary#

Text.TrimStart(s) and Text.TrimEnd(s) remove whitespace from one end of a string (Text.Trim(s) does both). Give any of the three a second argument and it removes those CHARACTERS instead — C#'s TrimEnd(params char[]), with the set written as a string because Osy# has no char type. Text.PadStart(s, width, pad) and Text.PadEnd(s, width, pad) grow a string to at least width characters by adding a fill on the left or right. Padding never shortens a string, and the fill is a string, not a single character.

Signature#

Text.TrimStart(<string> s) -> string          // strip leading whitespace
Text.TrimEnd(<string> s)   -> string          // strip trailing whitespace
Text.TrimStart(<string> s, <string> chars) -> string   // …or strip any of THESE characters
Text.TrimEnd(<string> s, <string> chars)   -> string
Text.Trim(<string> s, <string> chars)      -> string   // both ends
Text.PadStart(<string> s, <int> width, <string> pad) -> string   // fill on the LEFT to `width`
Text.PadEnd(<string> s, <int> width, <string> pad)   -> string   // fill on the RIGHT to `width`

Description#

Trimming characters rather than whitespace#

The second argument is a SET, not a suffix: every character in it is stripped from that end, repeatedly, exactly as C#'s char[] overload does. So TrimEnd("/") removes as many trailing slashes as there are, and TrimEnd("/\\") removes either kind.

string JoinUrl(string baseUrl, string path) {
  return Text.TrimEnd(baseUrl, "/") + "/" + Text.TrimStart(path, "/");
}

⚠ It is a set of characters, so TrimEnd(url, "/api") strips any trailing /, a, p or i — not the word "api". That is C#'s behaviour too, and it is the one thing about these overloads that surprises people.

Trimming uses the full Unicode whitespace set#

TrimStart/TrimEnd strip every leading/trailing whitespace character, not just the ASCII space — a tab, a newline, a no-break space ( ), an ideographic space ( ) are all removed. Only the named end is touched: Text.TrimStart(" hi ") is "hi " (trailing spaces survive).

Padding never truncates, and takes a WIDTH not a count-to-add#

width is the target length, not "how many characters to add". If the string is already at least that long it comes back unchanged: Text.PadStart("hello", 3, "0") is "hello". Otherwise the gap is filled to reach exactly width.

The pad is a STRING, cut to fit the gap#

The fill is repeated and then cut to exactly the deficit, so a multi-character pad can end mid-repeat: Text.PadStart("7", 3, "ab") fills two characters — "ab7" — and Text.PadEnd("7", 4, "ab") is "7aba". An empty pad is a no-op (it cannot fill anything), so Text.PadStart("x", 5, "") is "x" — it does not loop forever. For zero-padding a number, a format specifier like D5 or "00000" is usually clearer than padding a string — see format specifiers.

All four run in memory on a value already in hand.

Examples#

// Trim stray whitespace, then right-justify into a fixed-width column with leading zeros.
string Ticket(string code) {
  return Text.PadStart(Text.TrimEnd(Text.TrimStart(code)), 6, "0");
}
[Test]
void Text_affix_answers() {
  Assert.Equal("000042", Ticket("  42  "));

  Assert.Equal("hi  ", Text.TrimStart("  hi  "));   // only the leading end
  Assert.Equal("  hi", Text.TrimEnd("  hi  "));
  Assert.Equal("hi", Text.TrimStart(" hi"));        // an ideographic space is whitespace too

  Assert.Equal("007", Text.PadStart("7", 3, "0"));
  Assert.Equal("ab7", Text.PadStart("7", 3, "ab"));  // multi-char pad, cut to the 2-char gap
  Assert.Equal("hello", Text.PadStart("hello", 3, "0"));   // already long enough → unchanged
  Assert.Equal("x", Text.PadStart("x", 5, ""));      // empty pad → no-op, never an infinite loop
  Assert.Equal("700", Text.PadEnd("7", 3, "0"));
  Assert.Equal("7aba", Text.PadEnd("7", 4, "ab"));
}

See also#

Related

Text.Length, Text.IsEmpty, Text.IsBlank, Text.Contains, Text.StartsWith, Text.EndsWith

Ask a string a question without changing it: its length, whether it is empty or blank, and whether it contains, starts…

Text.TitleCase

Capitalises the first letter of each word and lower-cases the rest, leaving a word that is already entirely upper-case…

format specifiers

Formats a number to a string with a .NET format specifier — F2 for two decimal places, N0 for a grouped whole number, C…