Skip to main content

Text

Concatenation needs Text on both sides​

+ joins two Texts. "Count: " + 5 is not "Count: 5". It's the mixed-type fallback, Integer 0. Turn numbers, Bools and handles into Text with StringFormat first.

StringFormat(format, value0, value1)​

  • Replaces every {0} with value0 and every {1} with value1. Either value can be any kind. There's no {2} and no format specifiers such as {0:N2}.
  • It always takes three arguments. Pass "" for a value you don't use: StringFormat("{0} items", n, "").
  • For more than two values, nest calls or concatenate the results (see the example below).
  • A Real always shows six decimals (0.500000). Round it to an Integer first for a whole number, or scale it (MathRound(r * 100)) for fixed-point output.
  • {0} is replaced before {1}, so if value0's text itself contains {1}, that gets replaced too.
w = WindowGetActive();
s = StringFormat(StringFormat("{0} x {1} at ", WindowGetWidth(w), WindowGetHeight(w)) + "({0}, {1})",
WindowGetX(w), WindowGetY(w));
UtilityPrint(s); // e.g. 1280 x 720 at (100, 80)

Measuring, searching, slicing​

  • StringGetLength counts UTF-16 code units, not characters. An emoji outside the Basic Multilingual Plane counts as 2.
  • StringGetIndexOf(text, search) gives a 0-based index, or -1 when search isn't found. It's case-sensitive, and there's no "last index of" (scan with a loop).
  • StringGetSubstring(text, start, length): start is 0-based. A length running past the end is cut short, and a start at or past the end gives "". A negative start or length is an error and stops the action.
  • There's no indexing syntax (s[0]). Use StringGetSubstring(s, i, 1) for one character.
  • StringContains, StringStartsWith, StringEndsWith and StringReplace are exact and case-sensitive. For a case-insensitive test, lower-case both sides first.
  • StringToUpper/StringToLower follow the user's locale casing rules, so the Turkish dotted/dotless i is handled correctly.
  • StringTrim strips whitespace from both ends, including the \r left over from Windows \r\n line endings.
  • StringReplace and StringSplit stop the action if the search text or delimiter is empty.

Splitting is a cache you read by index​

A Value can't hold a list, so StringSplit(text, delimiter) stores the parts in the running script's context and returns how many there are. Read each part with StringGetSplitPartAt(i); an out-of-range index gives "". The next StringSplit in the same script replaces that cache, so copy a part into a variable before you split something else. Every …EnumerateAll, …FindAll… or …GetAll… builtin, paired with its …EnumeratedAt reader, works the same way.

Comparing text​

== is exact and case-sensitive. </> compare ordinally by UTF-16 code unit, which isn't dictionary order: every uppercase ASCII letter sorts before every lowercase one, and accented letters sort after z. Don't present that ordering to a user as alphabetical.