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}withvalue0and every{1}withvalue1. 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 ifvalue0'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
StringGetLengthcounts 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-1whensearchisn't found. It's case-sensitive, and there's no "last index of" (scan with a loop).StringGetSubstring(text, start, length):startis 0-based. Alengthrunning past the end is cut short, and astartat or past the end gives"". A negativestartorlengthis an error and stops the action.- There's no indexing syntax (
s[0]). UseStringGetSubstring(s, i, 1)for one character. StringContains,StringStartsWith,StringEndsWithandStringReplaceare exact and case-sensitive. For a case-insensitive test, lower-case both sides first.StringToUpper/StringToLowerfollow the user's locale casing rules, so the Turkish dotted/dotless i is handled correctly.StringTrimstrips whitespace from both ends, including the\rleft over from Windows\r\nline endings.StringReplaceandStringSplitstop 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.