UXText
UXText provides the common string operations that the base String does not:
trimming, splitting, joining, case folding, prefix/suffix/contains, and
single-character replacement.
Every method is static, and every result is a fresh buffer. Nothing is mutated in place, so the methods are safe to call on a literal, on a field, or on a pointer that other code still holds.
#use <UXKit> // or #import "UXText.xc"Overview
Section titled “Overview”UXText.trimWhitespace((u8*)" hello world \n"); // "hello world"UXText.toUpper((u8*)"Grand Bleu"); // "GRAND BLEU"UXText.hasSuffix((u8*)"system.fnt", (u8*)".fnt"); // true
Array<UXStrItem>* parts = UXText.split((u8*)"a,b,c", (u8)',');UXText.partAt(parts, 1); // "b"UXText.join(parts, (u8*)" | "); // "a | b | c"Split results come back as an Array of
UXStrItem. The box is needed because an
array holds objects and a bare u8* is not one. partAt unwraps
a part, so you rarely name the box.
split keeps empties, tokenize drops them
Section titled “split keeps empties, tokenize drops them”The two methods give different answers, and each is correct for a different job.
UXText.split((u8*)"a,,b", (u8)','); // 3: "a" "" "b"UXText.split((u8*)"a,b,", (u8)','); // 3: "a" "b" ""UXText.split((u8*)"", (u8)','); // 1: ""split is structural: a delimiter marks a field boundary, so an
empty field is a field. A CSV row needs this: a blank cell is a cell, and a
trailing comma means a trailing empty column.
Split and join also round-trip: join(split(s, ','), ",") returns s
unchanged, because the empty fields are kept.
UXText.tokenize((u8*)" ls -l /usr ", UXCharacterSet.whitespaceAndNewlines()); // 3: "ls" "-l" "/usr"tokenize is lexical: a run of delimiters is one gap, and
leading and trailing delimiters produce nothing. Use it to split a command line,
a sentence into words, or a space-separated attribute.
The delimiter also differs. split takes one byte; tokenize takes a
UXCharacterSet, so “break on comma,
semicolon or tab” is one set and one pass.
The character set is a parameter
Section titled “The character set is a parameter”trim also takes a set, so it can trim more than whitespace:
UXCharacterSet* quotes = new UXCharacterSet();quotes.addString((u8*)"\"'");UXText.trim((u8*)"\"quoted\"", quotes); // quotedtrimWhitespace covers the common case, such as a line read
from a file.
Bytes, ASCII, and UTF-8
Section titled “Bytes, ASCII, and UTF-8”These methods work on bytes. slen is a byte count, split takes a byte,
and toLower folds A–Z only; accented letters are left
alone.
UTF-8 is self-synchronizing, which limits the effect of this:
Predicates and their empty cases
Section titled “Predicates and their empty cases”UXText.contains((u8*)"abc", (u8*)""); // true — everything contains nothingUXText.hasPrefix((u8*)"abc", (u8*)""); // trueUXText.hasPrefix((u8*)"ab", (u8*)"abcdef"); // false — stops at the NULThe empty-needle answers match NSString. They let an empty search box match
everything without a special case.
A prefix longer than the string is safe: the comparison reaches the haystack’s NUL and fails there without reading past it.
Topics
Section titled “Topics”trim · trimWhitespace · split · tokenize · partAt · join · toLower / toUpper · hasPrefix · hasSuffix · contains · replaceChar · slen · dup
static u8* trim(u8* s, UXCharacterSet* cs)Removes leading and trailing characters that are in the set. A string made
entirely of delimiters becomes "".
trimWhitespace
Section titled “trimWhitespace”static u8* trimWhitespace(u8* s)trim with
whitespaceAndNewlines.
static Array<UXStrItem>* split(u8* s, u8 delim)Splits on one byte, keeping empty fields. Always returns at least one part.
tokenize
Section titled “tokenize”static Array<UXStrItem>* tokenize(u8* s, UXCharacterSet* sep)Splits on any character in the set, dropping empty fields. A string made entirely of delimiters gives an empty array.
partAt
Section titled “partAt”static u8* partAt(Array<UXStrItem>* parts, i32 i)Unwraps one part, so you do not need to name
UXStrItem.
static u8* join(Array<UXStrItem>* parts, u8* sep)Concatenates with a separator between parts, with none leading or trailing.
An empty array gives "".
toLower / toUpper
Section titled “toLower / toUpper”static u8* toLower(u8* s)static u8* toUpper(u8* s)ASCII case folding. See above.
hasPrefix
Section titled “hasPrefix”static bool hasPrefix(u8* s, u8* p)hasSuffix
Section titled “hasSuffix”static bool hasSuffix(u8* s, u8* suf)The extension test. False when the suffix is longer than the string.
contains
Section titled “contains”static bool contains(u8* hay, u8* needle)Substring search. True for an empty needle. See the caution on cost.
replaceChar
Section titled “replaceChar”static u8* replaceChar(u8* s, u8 from, u8 to)Replaces every occurrence of one byte with another, in a new buffer. The length is preserved, so this cannot replace a character with a string; use split and join for that.
static i32 slen(u8* s)Byte length. Null-safe: returns 0 for null, so the other methods do not
each need a null guard.
static u8* dup(u8* s, i32 start, i32 len)A fresh NUL-terminated copy of a range. A negative length is clamped to zero.
Example
Section titled “Example”trim: 'hello world'unquote: quotedsplit a,,b -> 3: [a] [] [b]split a,b, -> 3: [a] [b] []split '' -> 1: []tokenize -> 3: [ls] [-l] [/usr]join: a | | bround trip: a,b,prefix=1 suffix=1 contains=1empty needle=1 empty prefix=1long prefix=0case: GRAND BLEU grand bleuThe program is website/site/examples/uxkit/strings.xc. The doc-examples
gate compiles it, and the output above is what it prints.
Conforms to
Section titled “Conforms to”- A plain class (not an
Objectsubclass). All methods are static, so there is nothing to instantiate.
See also
Section titled “See also”UXStr: concatenation and number conversionUXStrItem: the box split results come inUXCharacterSet: the delimiter setsUXCSV: when the fields are quoted andsplitis not enough