Programming Language Cheat Sheets: Strings

Strings Mathematics Operators and Symbols [string interpolation] General (Control Flow/Debugging) [multi-line strings] Dates Objects [Array.Join/Array.ToString, Array.Print/Map.Print] New Features Timelines Sections: The Universal Function Library Project: Details Links (Format/Sprintf) Links (Escape Characters) Note: UFL: Universal Function Library, a set of around 100-300 standard functions for all programming languages. Languages do not have to implement anything exactly to the UFL specification, it is a guide. See lower down for further details. UFL: (StringNewDemo) [or StrNewDemo][create a string] AutoHotkey: vText := "abc" [type: String] C++: std::string vText = "abc" [type (std::string): NSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE] [WARNING: auto vText = "abc" resolves to type 'PKc' (i.e. char array, not std::string)] C#: var vText = "abc" [type: String] [note: 'var'/'string'/'String' resolve to String] Crystal: vText = "abc" [type: String] Excel: abc [type: 2 (Text)] Excel VBA: vText = "abc" [type: String] Go: vText := "abc" [type: string] [also: var oSB strings.Builder] [type (Builder): strings.Builder] Java: var vText = "abc" [type: String] [note: 'var'/'String' resolve to String] JavaScript: vText = "abc" [type: string] Kotlin: var vText = "abc" [type: String] PHP: $vText = "abc" [type: string] Python: vText = "abc" [type: str] R: vText = "abc" [type: character] [WARNING: 'character', not 'string'] Ruby: vText = "abc" [type: String] Rust: let vText = "abc" [type: &str] [also: let vText = "abc".to_string()] [type (to_string): String] [also: let mut vText = "abc"] Scala: var vText = "abc" [type: String] [also: var vText: String = "abc"] Swift: var vText = "abc" [type: String] UFL: (CharNewDemo) [create a character][see also: IntToChar/StrToChar] AutoHotkey: ___ C++: auto vChar = 'a' [e.g. (UTF-8 byte)] [type: c] [note: 'auto'/'char' resolve to type 'c'] C#: var vChar = 'a' [e.g. (UTF-16 short)] [type: Char] [note: 'var'/'char'/'Char' resolve to Char] Crystal: vChar = 'a' [e.g. (codepoint)] [type: Char] Excel: ___ Excel VBA: ___ Go: ___ [note: there is no 'char' type, e.g. creates an int32: vChar := 'a'] [type ('a'): int32] Java: var vChar = 'a' [e.g. (UTF-16 short)] [type: char] [note: 'var'/'char' resolve to char] [note: 'char' (lower case), 'String' (title case)] JavaScript: ___ Kotlin: var vChar = 'a' [e.g. (UTF-16 short)] [type: Char] PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: let vChar = 'a' [e.g. (codepoint)] [type: char] [also: let mut vChar = 'a'] Scala: var vChar = 'a' [e.g. (UTF-16 short)] [type: char] Swift: var vChar: Character = "a" [e.g. (codepoint)] [type: Character] [also: var vChar = Array("a")[0]] [note: can't use single quotes to create a char] UFL: String [or ToString/AnyToString/ValueToString][anything listed here handles strings/ints/floats/objects, where objects include arrays/maps] AutoHotkey: String [e.g. String(vVar)] [note: handles string/int/float and any object with a ToString method] [WARNING: currently doesn't work on built-in Array/Map/Object] C++: ___ [WARNING: no general approaches for primitives/arrays/maps] [WARNING: std::to_string fails on std::string itself] C#: ___ [WARNING: no general approaches for primitives/arrays/maps] Crystal: to_s [e.g. vVar.to_s] Excel: ___ Excel VBA: ___ Go: fmt.Sprintf [e.g. fmt.Sprintf("%v", vVar)] Java: ___ [WARNING: no general approaches for primitives/arrays/maps] JavaScript: String [e.g. String(vVar)] [note: works on arrays] [WARNING: only prints '[object Map]' / '[object Object]' for Map/Object types] Kotlin: toString [e.g. vVar.toString()] [WARNING: toString() only prints type name for arrays] [also: oArrayAny.toList().toString()] PHP: var_export [e.g. var_export($vVar, true)] [also: print_r($vVar, true)] Python: str [e.g. str(vVar)] R: toString [e.g. toString(vVar)] [also: capture.output(print(vVar))] Ruby: to_s [e.g. vVar.to_s] Rust: format [e.g. format!("{:?}", vVar)] [e.g. format!("{:#?}", vVar)] Scala: toString [WARNING: toString only prints type name for arrays] Swift: String [e.g. String(describing:vVar)] [e.g. vVar.description] [e.g. String(reflecting:vVar)] UFL: NumToString [or IntToString/IntegerToString/FloatToString] AutoHotkey: String [e.g. String(vNum)] C++: std::to_string [e.g. std::to_string(vNum)] C#: ToString [e.g. vNum.ToString()] Crystal: to_s [e.g. vNum.to_s] Excel: TEXT [e.g. TEXT(A1,"General")] [also: =""&A1] Excel VBA: CStr [e.g. CStr(vNum)] Go: fmt.Sprintf [e.g. fmt.Sprintf("%v", vNum)] Java: String.valueOf [e.g. String.valueOf(vNum)] [also: Integer.toString(vNum)] [also: Double.toString(vNum)] [also: "" + vNum] JavaScript: String [e.g. String(vNum)] Kotlin: toString [e.g. vNum.toString()] PHP: strval [e.g. strval($vNum)] Python: str [e.g. str(vNum)] R: as.character [e.g. as.character(vNum)] [also: paste(vNum)] [also: toString(vNum)] Ruby: to_s [e.g. vNum.to_s] Rust: to_string [e.g. vNum.to_string()] [also: format!("{}", vNum)] Scala: toString [e.g. vNum.toString] [also: "" + vNum] Swift: String [e.g. String(vNum)] UFL: ObjToString [or ObjectToString][note: oArrayAny indicates works on int/float/string arrays, oArrayStr indicates works on string arrays only][see also: Array.ToString] AutoHotkey: String [e.g. String(oObj)] [note: handles any object with a ToString method] C++: ___ C#: ___ [can use: String.Join(vSep, oArrayAny)] Crystal: to_s [e.g. oArrayAny.to_s] Excel: ___ Excel VBA: ___ [can use: Join(oArrayAny, vSep)] Go: fmt.Sprintf [e.g. fmt.Sprintf("%v", oArrayAny)] Java: ___ [e.g. java.util.Arrays.toString(oArrayAny)] [e.g. String.join(vSep, oArrayStr)] JavaScript: String [e.g. String(oArrayAny)] [e.g. oArrayAny.join(vSep)] Kotlin: ___ [e.g. oArrayAny.joinToString(vSep)] [e.g. oArrayAny.toList().toString()] PHP: strval [e.g. implode($vSep, $oArrayAny)] [e.g. $vText = var_export($oArrayAny, true)] Python: str [e.g. str(oListAny)] [e.g. vSep.join(oListStr)] [e.g. vSep.join(map(str, oListAny))] R: toString [e.g. toString(oVecAny)] Ruby: to_s [e.g. oArrayAny.to_s] Rust: format [e.g. format!("{:?}", oArrayAny)] [e.g. format!("{:#?}", oArrayAny)] Scala: toString [e.g. oObj.toString] [can use: oArrayAny.mkString(vSep)] [WARNING: toString only prints type name for arrays] Swift: String [e.g. String(describing:oArrayAny)] [e.g. oArrayAny.description] [e.g. String(reflecting:oArrayAny)] [e.g. oArrayStr.joined(separator:vSep)] UFL: CharToStr [CharToString][char type to string type][see also: ChrAt/Chr] AutoHotkey: ___ C++: std::string [e.g. std::string(1, vChar)] [can use: std::string("") + vChar] C#: Char.ToString [e.g. Char.ToString(vChar)] [also: "" + vChar] Crystal: to_s [e.g. vChar.to_s] [also: "" + vChar] Excel: ___ Excel VBA: ___ Go: ___ [note: there is no 'char' type, e.g. 'a' creates an int32, e.g. rune(97) creates an int32] [also (int to string): string(vOrd)] Java: String.valueOf [e.g. String.valueOf(vChar)] [also: Character.toString(vChar)] [also: "" + vChar] JavaScript: ___ Kotlin: toString [e.g. vChar.toString()] [also: Character.toString(vChar)] [also: "" + vChar] [also: String(charArrayOf(vChar))] PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: to_string [e.g. vChar.to_string()] [also: String::from(vChar)] [also: format!("{}", vChar)] Scala: toString [e.g. vChar.toString] [also: String.valueOf(vChar)] [also: Character.toString(vChar)] [also: "" + vChar] Swift: String [e.g. String(vChar)] UFL: StrToChar [StringToChar][get first char of string as a char][string type to char type][string to char][see also: Ord/ChrAt] AutoHotkey: ___ C++: ___ [can use (UTF-8 byte): vText[0]] C#: ___ [can use (UTF-16 short): vText[0]] Crystal: ___ [can use (codepoint): vText[0]] [also (codepoint): vText.chars[0]] Excel: ___ Excel VBA: ___ Go: ___ [note: there is no 'char' type, e.g. 'a' creates an int32] [can use (codepoint): []rune(vText)[0]] Java: charAt [e.g. (UTF-16 short): vText.charAt(0)] JavaScript: ___ Kotlin: ___ [can use (UTF-16 short): vText[0]] PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: nth [e.g. (codepoint): vText.chars().nth(0).unwrap()] [also (UTF-8 byte): char::from(vText.as_bytes()[0])] Scala: charAt [e.g. (UTF-16 short): vText.charAt(0)] [also: (UTF-16 short): vText[0]] Swift: ___ [can use (codepoint): Array(vText)[0]] UFL: CharToInt [char type to int type] AutoHotkey: ___ C++: ___ [e.g. (int)(unsigned char)vChar] C#: ___ [e.g. (int)vChar] Crystal: ord [e.g. vChar.ord] Excel: ___ Excel VBA: ___ Go: ___ [note: there is no 'char' type, e.g. 'a' creates an int32] Java: ___ [e.g. (int)vChar] JavaScript: ___ Kotlin: code [e.g. vChar.code] PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: ___ [e.g. vChar as i32] [also: u32::from(vChar) as i32] [also: into] Scala: ___ [e.g. vChar.toInt] Swift: ___ [e.g. vChar.unicodeScalars.first!.value] UFL: IntToChar [or CharNewDemo][int type to char type] AutoHotkey: ___ C++: ___ [e.g. (char)vOrd] C#: ___ [e.g. (char)vOrd] Crystal: chr [e.g. vOrd.chr] Excel: ___ Excel VBA: ___ Go: ___ [note: there is no 'char' type, e.g. 'a' creates an int32] [also (some methods expect a rune): rune(vOrd)] Java: ___ [e.g. (char)vOrd] JavaScript: ___ Kotlin: toChar [e.g. vOrd.toChar()] PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: char::from_u32 [e.g. i32: char::from_u32(vOrd as u32).unwrap()] [also: char::from_u32_unchecked] [also: chars 0-255: vOrd as u8 as char] [also: chars 0-255: char::from(vOrd as u8)] [also: try_into] Scala: ___ [e.g. vOrd.toChar] Swift: ___ [e.g. Character(UnicodeScalar(vOrd)!)] UFL: IsString [or VarIsString/Any.IsString][check if variable is of string type][see also: Any.IsTypeDemo] AutoHotkey: ___ [e.g. vVar is String] [note: AHK v2 onwards] C++: ___ [e.g. std::is_same<decltype(vVar),std::string>::value] C#: ___ [e.g. vVar is String] Crystal: ___ [e.g. vVar.is_a? String] Excel: ___ [e.g. =ISTEXT(A1)] [also: =TYPE(A1)=2] Excel VBA: ___ [e.g. TypeName(vVar) = "String"] Go: ___ [e.g. fmt.Sprintf("%T", vVar) == "string"] Java: ___ [e.g. ((Object)vVar).getClass().equals(String.class)] JavaScript: ___ [e.g. typeof vVar === "string"] Kotlin: ___ [e.g. vVar is String] PHP: ___ [e.g. is_string($vVar)] [also: gettype($vVar) == "string"] Python: ___ [e.g. isinstance(vVar, str)] [also: type(vVar) is str] [WARNING: returns False: "abc" is str] R: ___ [e.g. is.character(vVar)] [also: typeof(vVar) == "character"] Ruby: ___ [e.g. vVar.is_a? String] Rust: ___ [e.g. type_name_of_val(&vVar) == "&str"] [requires: use std::any::type_name_of_val] [also: compare against "alloc::string::String"] Scala: ___ [e.g. vVar.isInstanceOf[String]] Swift: ___ [e.g. vVar is String] UFL: StrLower [make all characters lower case] AutoHotkey: StrLower [e.g. StrLower(vText)] C++: tolower [e.g. (modifies string): std::transform(vText.begin(), vText.end(), vText.begin(), ::tolower)] [also: std::tolower(vChar)] C#: ToLower [e.g. vText.ToLower()] Crystal: downcase [e.g. vText.downcase] Excel: LOWER [e.g. LOWER(A1)] Excel VBA: LCase [also: StrConv] [e.g. LCase(vText)] Go: strings.ToLower [e.g. strings.ToLower(vText)] Java: toLowerCase [e.g. vText.toLowerCase()] JavaScript: toLowerCase [e.g. vText.toLowerCase()] Kotlin: lowercase [e.g. vText.lowercase()] [deprecated: toLowerCase] PHP: mb_strtolower [e.g. mb_strtolower($vText)] [WARNING: strtolower modifies ASCII letters only] Python: str.lower [e.g. vText.lower()] R: tolower [e.g. tolower(vText)] Ruby: downcase [e.g. vText.downcase] Rust: to_lowercase [e.g. vText.to_lowercase()] [also: to_ascii_lowercase] Scala: toLowerCase [e.g. vText.toLowerCase] Swift: lowercased [e.g. vText.lowercased()] UFL: StrUpper [make all characters upper case] AutoHotkey: StrUpper [e.g. StrUpper(vText)] C++: toupper [e.g. (modifies string): std::transform(vText.begin(), vText.end(), vText.begin(), ::toupper)] [also: std::toupper(vChar)] C#: ToUpper [e.g. vText.ToUpper()] Crystal: upcase [e.g. vText.upcase] Excel: UPPER [e.g. UPPER(A1)] Excel VBA: UCase [also: StrConv] [e.g. UCase(vText)] Go: strings.ToUpper [e.g. strings.ToUpper(vText)] Java: toUpperCase [e.g. vText.toUpperCase()] JavaScript: toUpperCase [e.g. vText.toUpperCase()] Kotlin: uppercase [e.g. vText.uppercase()] [deprecated: toUpperCase] PHP: mb_strtoupper [e.g. mb_strtoupper($vText)] [WARNING: strtoupper modifies ASCII letters only] Python: str.upper [e.g. vText.upper()] R: toupper [e.g. toupper(vText)] Ruby: upcase [e.g. vText.upcase] Rust: to_uppercase [e.g. vText.to_uppercase()] [also: to_ascii_uppercase] Scala: toUpperCase [e.g. vText.toUpperCase] Swift: uppercased [e.g. vText.uppercased()] UFL: (StrUpperFirstOnly) [make first char upper case (capitalise it), leave other chars unchanged][see also: StrFirst] AutoHotkey: ___ [can use (UTF-16 shorts): vTextNew := StrUpper(SubStr(vText, 1, 1)) SubStr(vText, 2)] [also (codepoints): vTextNew := RegExReplace(vText, "^.", "$U0")] C++: ___ [can use (UTF-8 bytes): std::transform with ::toupper, and substr] [also (UTF-8 bytes) (to uppercase 1 byte): vTextNew = (char)std::toupper(vText[0]) + vText.substr(1)] C#: ___ [can use (UTF-16 shorts): vTextNew = vText.Substring(0, 1).ToUpper() + vText.Substring(1)] [also (UTF-16 shorts): vTextNew = vText.Substring(0, 1).ToUpper() + vText.Remove(0, 1)] Crystal: ___ [can use (codepoints): vTextNew = vText[0].upcase + vText[1..]] [WARNING: capitalize makes the 2nd char onwards lower case] Excel: ___ [can use (UTF-16 shorts): UPPER(LEFT(A1))&MID(A1,2,LEN(A1))] Excel VBA: ___ [can use (UTF-16 shorts): vTextNew = UCase(Left(vText, 1)) & Mid(vText, 2)] Go: ___ [can use (codepoints): vTextNew := strings.ToUpper(string([]rune(vText)[0])) + string([]rune(vText)[1:])] Java: ___ [can use (UTF-16 shorts): vTextNew = vText.substring(0, 1).toUpperCase() + vText.substring(1)] JavaScript: ___ [can use (codepoints): vTextNew = [...vText][0].toUpperCase() + vText.slice([...vText][0].length)] [can use (UTF-16 shorts): vTextNew = vText.charAt().toUpperCase() + vText.slice(1)] Kotlin: ___ [can use (UTF-16 shorts): vTextNew = vText.replaceFirstChar{it.uppercase()}] [can use (UTF-16 shorts): vTextNew = vText.take(1).uppercase() + vText.drop(1)] [note: deprecated: vText.capitalize()] PHP: ___ [can use (codepoints): $vTextNew = mb_strtoupper(mb_substr($vText, 0, 1)) . mb_substr($vText, 1)] [note: ucfirst only uppercases ASCII chars] Python: capitalize [e.g. (codepoints): vTextNew = vText.capitalize()] [also (codepoints): vTextNew = vText[0].upper() + vText[1:]] R: ___ [can use (codepoints): vTextNew = paste0(toupper(substr(vText, 1, 1)), substring(vText, 2))] [also (codepoints, modify string): substr(vText, 1, 1) = toupper(substr(vText, 1, 1))] Ruby: ___ [can use (codepoints): vTextNew = vText.slice(0).upcase + vText.slice(1..)] [also (codepoints): vTextNew = vText[0].upcase + vText[1..]] [also (codepoints, modify string): vText[0] = vText[0].upcase] [WARNING: capitalize makes the 2nd char onwards lower case] Rust: ___ [can use (codepoints): vTextNew: String = vText.chars().take(1).collect::<String>().to_uppercase() + &vText.chars().skip(1).collect::<String>()] [also: vTextNew = format!("{}{}", vText.chars().next().unwrap().to_uppercase(), vText.chars().skip(1).collect::<String>())] [also (for a mutable string): vTextNew = vText.remove(0).to_uppercase().to_string() + &vText] Scala: capitalize [e.g. (UTF-16 shorts) vText.capitalize] [also (UTF-16 shorts): vTextNew = vText.substring(0, 1).toUpperCase() + vText.substring(1)] Swift: ___ [can use (codepoints): vTextNew = vText.prefix(1).uppercased() + vText.dropFirst()] UFL: StrTitle [set all words to title case][capitalise first char in each word (and possibly make all other chars lower case)] AutoHotkey: StrTitle C++: ___ C#: ___ Crystal: ___ Excel: PROPER Excel VBA: WorksheetFunction.Proper [also: StrConv with vbProperCase] Go: ___ [deprecated: strings.Title(vText)] [WARNING: strings.Title capitalises the first letter in each word, strings.ToTitle makes every char 'title case' (which often makes every char upper case)] Java: ___ JavaScript: ___ Kotlin: ___ PHP: mb_convert_case [e.g. mb_convert_case($vText, MB_CASE_TITLE)] Python: str.title [e.g. vText.title()] R: tools::toTitleCase [tools::toTitleCase(vText)] [note: is base R] [WARNING: skips some common English words] Ruby: ___ Rust: ___ Scala: ___ Swift: capitalized [e.g. vText.capitalized] [requires: import Foundation] UFL: StrCompare [case-sensitive][compares strings and returns 1/0/-1 accordingly (or positive/0/negative)][see also: StrEquals/NumCompare/Array.Sort/StrDiffFirst] AutoHotkey: StrCompare [WARNING: case-insensitive by default] [e.g. case-sensitive: vCmp := StrCompare(vTextA, vTextB, 1)] [note (since AHK v2): < > can't compare strings] C++: compare [e.g. vCmp = vTextA.compare(vTextB)] [also: <=> < >] [also: memcmp/strcmp/strncmp/wcscmp/wcsncmp] C#: String.Compare [e.g. vCmp = String.Compare(vTextA, vTextB)] [also: vCmp = vTextA.CompareTo(vTextB)] [note: < > can't compare strings] Crystal: compare [e.g. vCmp = vTextA.compare(vTextB)] [can use: <=> < >] [e.g. vTextA <=> vTextB] Excel: ___ [WARNING: case-insensitive: < > =] [can use (case-insensitive): =IF(A1<B1,-1,A1>B1)+0] [also (case-sensitive equals): EXACT()] Excel VBA: StrComp [e.g. vCmp = StrComp(vTextA, vTextB)] [can use: < >] Go: strings.Compare [e.g. vCmp := strings.Compare(vTextA, vTextB)] [also: cmp.Compare()] [can use: < >] Java: compareTo [e.g. vCmp = vTextA.compareTo(vTextB)] [also: compareToIgnoreCase] [note: < > can't compare strings] JavaScript: ___ [can use (< >): vCmp = +(vTextA>vTextB)||-(vTextA<vTextB)] [also: vCmp = (vTextA>vTextB)?1:(vTextA<vTextB)?-1:0] [WARNING: localeCompare appears to lack a way to do a default string sort, i.e. no case-sensitive sort by Unicode codepoints] Kotlin: compareTo [e.g. vCmp = vTextA.compareTo(vTextB)] [can use: < >] PHP: substr_compare [e.g. case-sensitive: $vCmp = substr_compare($vTextA, $vTextB, 0)] [e.g. case-insensitive: substr_compare($vTextA, $vTextB, 0, null, true)] [WARNING: avoid comparison operators such as < > <=> because they compare numeric-looking strings numerically e.g. ("aa" < "b") returns true but ("11" < "2") returns false] Python: ___ [can use: < >] [can use: vCmp = +(vTextA>vTextB) or -(vTextA<vTextB)] R: ___ [can use (locale comparison): < >] [can use (locale comparison): vCmp = (if (vTextA<vTextB) -1 else +(vTextA>vTextB))] [WARNING: R uses the locale for string comparison, e.g. for locale 'en_US.UTF-8', ("ABC" > "abc") returns TRUE, which is unusual, for a case-sensitive Unicode codepoint comparison, that returns FALSE] [note: for a more standard comparison, use locale 'C', e.g. Sys.setlocale("LC_COLLATE", "C")] Ruby: ___ [can use: <=> < >] [e.g. vCmp = vTextA <=> vTextB] [also (case-insensitive): casecmp] Rust: cmp [e.g. vCmp = vTextA.cmp(vTextB) as i32] [can use: < >] Scala: compare [e.g. vCmp = vTextA.compare(vTextB)] [also: vTextA.compareTo(vTextB)] [also: compareToIgnoreCase] [can use: < >] Swift: compare [e.g. vCmp = vTextA.compare(vTextB).rawValue] [can use: < >] [requires (compare): import Foundation] UFL: StrCompareCasIns [case-insensitive][compares strings and returns 1/0/-1 accordingly (or positive/0/negative)][see also: StrEquals/NumCompare/Array.Sort/StrDiffFirst] AutoHotkey: StrCompare [WARNING: case-insensitive by default] [e.g. case-insensitive: StrCompare(vText1, vText2)] [note (since AHK v2): < > can't compare strings] C++: ___ C#: String.Compare [e.g. String.Compare(vTextA, vTextB, StringComparison.OrdinalIgnoreCase)] [note: < > can't compare strings] Crystal: compare [e.g. case-insensitive: vTextA.compare(vTextB, true)] Excel: ___ [can use (case-insensitive): < > =] Excel VBA: StrComp [e.g. StrComp(vTextA, vTextB, 1)] Go: ___ [also (case-insensitive equals): strings.EqualFold] Java: compareToIgnoreCase [e.g. vTextA.compareToIgnoreCase(vTextB)] [note: < > can't compare strings] JavaScript: localeCompare [e.g. vTextA.localeCompare(vTextB, undefined, {sensitivity:"accent"})] Kotlin: ___ PHP: strcasecmp [e.g. case-insensitive: strcasecmp($vTextA, $vTextB)] [e.g. case-insensitive: substr_compare($vTextA, $vTextB, 0)] [WARNING (substr_compare): case-insensitive by default] [WARNING (strcasecmp/substr_compare): only ASCII chars are compared case-insensitively, other chars are compared case-sensitively] Python: ___ R: ___ Ruby: casecmp [e.g. case-insensitive: vTextA.casecmp(vTextB)] Rust: ___ Scala: compareToIgnoreCase [e.g. vTextA.compareToIgnoreCase(vTextB)] [can use: < >] Swift: caseInsensitiveCompare [e.g. vTextA.caseInsensitiveCompare(vTextB)] [also: vTextA.compare(vTextB, options:.caseInsensitive)] [requires (caseInsensitiveCompare/compare): import Foundation] UFL: StrEquals [see also: StrCompare/StrContains/StrStarts/StrEnds] AutoHotkey: ___ [can use: ==] [note: case-insensitive: =] C++: ___ [can use: ==] C#: String.Equals [e.g. String.Equals(vTextA, vTextB)] [can use: ==] Crystal: ___ [can use: ==] [also: vTextA.compare(vTextB).zero?] Excel: EXACT [can use (case-insensitive): =] Excel VBA: ___ [can use: =] [WARNING: = is case-sensitive in Excel VBA, but case-insensitive in Excel sheet formulas] Go: ___ [can use: ==] Java: equals [e.g. vTextA.equals(vTextB)] [can use: ==] [also: equalsIgnoreCase] [MAJOR WARNING (false): "aa".split("")[0] == "a"] [note (true): "aa".split("")[0].equals("a")] JavaScript: ___ [can use: ==] Kotlin: equals [e.g. vTextA.equals(vTextB)] [can use: ==] PHP: ___ [can use: ==] Python: operator.eq [can use: ==] R: ___ [can use: ==] Ruby: eql [e.g. vTextA.eql?(vTextB)] [can use: ==] [also (case-insensitive, returns bool): vTextA.casecmp?(vTextB)] Rust: eq [e.g. vTextA.eq(vTextB)] [can use: ==] [also: eq_ignore_ascii_case] Scala: equals [e.g. vTextA.equals(vTextB)] [can use: ==] [also: equalsIgnoreCase] Swift: elementsEqual [e.g. vTextA.elementsEqual(vTextB)] [can use: ==] UFL: StrEqualsCasIns [see also: StrCompare/StrContains/StrStarts/StrEnds] AutoHotkey: ___ [can use (case-insensitive): =] [also (case-insensitive): vIsMatch := !StrCompare(vText1, vText2)] C++: ___ C#: String.Equals [e.g. String.Equals(vTextA, vTextB, StringComparison.OrdinalIgnoreCase)] Crystal: compare [e.g. case-insensitive: vTextA.compare(vTextB, true).zero?] Excel: ___ [can use (case-insensitive): =] Excel VBA: ___ [can use: vIsMatch = (StrComp(vTextA, vTextB, 1) = 0)] Go: strings.EqualFold [e.g. strings.EqualFold(vTextA, vTextB)] Java: equalsIgnoreCase [e.g. vTextA.equalsIgnoreCase(vTextB)] JavaScript: ___ [can use: vIsMatch = !vTextA.localeCompare(vTextB, undefined, {sensitivity:"accent"})] Kotlin: equals [e.g. vTextA.equals(vTextB, ignoreCase = true)] PHP: ___ [can use (case-insensitive): $vIsMatch = !strcasecmp($vTextA, $vTextB)] [also (case-insensitive): $vIsMatch = !substr_compare($vTextA, $vTextB, 0)] [WARNING (strcasecmp/substr_compare): only ASCII chars are compared case-insensitively, other chars are compared case-sensitively] Python: ___ R: ___ Ruby: casecmp [e.g. case-insensitive, returns bool: vTextA.casecmp?(vTextB)] Rust: ___ [can use: vTextA.eq_ignore_ascii_case(vTextB)] Scala: equalsIgnoreCase [e.g. vTextA.equalsIgnoreCase(vTextB)] Swift: ___ [can use: vIsMatch = (vTextA.caseInsensitiveCompare(vTextB).rawValue == 0)] [requires: import Foundation] UFL: (StrClamp) [clamp a string (inclusive end)][equivalent to obtaining the median of 3 strings][see also: StrBetween/Clamp/StrCompare] AutoHotkey: ___ C++: std::clamp [e.g. std::clamp(vText, vMin, vMax)] C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ [can use (median): median(c(vText, vMin, vMax))] Ruby: ___ Rust: clamp [e.g. vText.clamp(vMin, vMax)] Scala: ___ [can use (median): vTextNew = Array(vText, vMin, vMax).sorted.toList(1)] Swift: ___ UFL: (StrBetween) [inclusive to inclusive][return if string is between min/max][see also: Between/StrClamp/StrCompare] AutoHotkey: ___ C++: ___ [can use: std::clamp(vText, vMin, vMax) == vText] C#: ___ Crystal: ___ [can use: (vMin..vMax) === vText] [also: (vMin..vMax).includes?(vText)] Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: contains [e.g. (vMin..vMax).contains(vText)] PHP: ___ Python: ___ R: ___ [can use (median): median(c(vText, vMin, vMax)) == vText] Ruby: between [e.g. vText.between?(vMin, vMax)] [also: (vMin..vMax) === vText] [also: (vMin..vMax).cover?(vText)] [also (if strings same length): (vMin..vMax).include?(vText)] Rust: ___ [can use: vText.clamp(vMin, vMax) == vText] Scala: ___ Swift: ___ UFL: (StrBetweenUntil) [inclusive to exclusive][return if string is between min/max][see also: BetweenUntil/StrClamp/StrCompare] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ [can use: (vMin...vMax) === vText] [also: (vMin...vMax).includes?(vText)] Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: contains [e.g. (vMin..<vMax).contains(vText)] PHP: ___ Python: ___ R: ___ Ruby: ___ [can use: (vMin...vMax) === vText] [also: (vMin...vMax).cover?(vText)] [also (if strings same length): (vMin...vMax).include?(vText)] Rust: ___ Scala: ___ Swift: ___ UFL: Chr [or Char/IntToStrChar/IntToStringChar][codepoint to character (as string)][i.e. int to char to string][see also: IntToChar] AutoHotkey: Chr [e.g. (codepoints 0-1114111): Chr(vOrd)] C++: ___ [e.g. (ASCII: codepoints 0-127): std::string vChar{(char)vOrd}] [e.g. treble clef: std::string vChar{(char)240,(char)157,(char)132,(char)158}] [note: std::string stores strings as bytes (UTF-8)] C#: ConvertFromUtf32 [e.g. (codepoints 0-1114111): Char.ConvertFromUtf32(vOrd)] [note: this does output a string] Crystal: chr [e.g. (codepoints 0-1114111): vOrd.chr.to_s] Excel: UNICHAR [e.g. (codepoints 0-1114111): UNICHAR(A1)] [note: UNICHAR (Excel 2013)] [WARNING: CHAR only handles codepoints 0-127 (ASCII) reliably] Excel VBA: ChrW [e.g. (codepoints 0-65535): ChrW(vOrd)] [e.g. treble clef: ChrW(55348) & ChrW(56606)] Go: string [e.g. (codepoints 0-1114111): string(vOrd)] [WARNING: e.g. string(97) returns string 'a' not string '97'] Java: ___ [can use (codepoints 0-1114111): new String(new int[]{vOrd}, 0, 1)] [also (codepoints 0-1114111): Character.toString(vOrd)] [also (codepoints 0-1114111): new String(Character.toChars(vOrd))] [WARNING: Java chars go up to 0xFFFF (not 0xFF)] JavaScript: String.fromCodePoint [e.g. (codepoints 0-1114111): String.fromCodePoint(vOrd)] [also: String.fromCharCode(), e.g. treble clef: String.fromCharCode(55348, 56606)] Kotlin: toString [e.g. (codepoints 0-1114111): Character.toString(vOrd)] PHP: mb_chr [e.g. (codepoints 0-1114111): mb_chr($vOrd)] [WARNING: chr only handles codepoints 0-255] Python: chr [e.g. (codepoints 0-1114111): chr(vOrd)] R: intToUtf8 [e.g. (codepoints 0-1114111): intToUtf8(vOrd)] [note: if passed a vector, returns a multi-char string] Ruby: chr [e.g. (codepoints 0-1114111): vOrd.chr(Encoding::UTF_8)] Rust: ___ [can use (codepoints 0-1114111): char::from_u32(vOrd as u32).unwrap().to_string()] Scala: ___ [can use (codepoints 0-1114111): String(Array(vOrd), 0, 1)] [also (codepoints 0-1114111): Character.toString(vOrd)] [also (codepoints 0-1114111): String(Character.toChars(vOrd))] [also (codepoints 0-65535): vOrd.toChar.toString] [WARNING: Scala chars go up to 0xFFFF (not 0xFF)] Swift: ___ [can use (codepoints 0-1114111): String(UnicodeScalar(vOrd)!)] UFL: (IntToStrCharEscapeDemo) [or IntToStringCharEscapeDemo][e.g. concatenate 3 chars: "√𝄞] AutoHotkey: ___ [can use: Chr(0x22) Chr(0x221A) Chr(0x1D11E)] [note: string literal concatenation] [also: Format("{:c}{:c}{:c}{:c}", 0x22, 0x221A, 0xD834, 0xDD1E)] [can use (with RegExMatch/RegExReplace needles): "\x22" "\x{221A}" "\x{1D11E}"] C++: "\u0022" "\u221A" "\U0001D11E" [also (C++23): "\u{1D11E}"] [note: string literal concatenation] [WARNING: \x has max 255 but consumes as many hex chars as possible] C#: "\u0022" + "\u221A" + "\U0001D11E" [also: "\x0022" + "\x221A"] Crystal: "\x22" + "\u221A" + "\u{1D11E}" Excel: ___ Excel VBA: ___ [can use: ChrW(&H22) & ChrW(&H221A) & ChrW(&HD834) & ChrW(&HDD1E)] Go: "\x22" + "\u221A" + "\U0001D11E" Java: "\u005C\u0022" + "\u221A" + "\uD834\uDD1E" [MAJOR WARNING: Java replaces escaped chars, including in comments, before parsing the source code] [note: '\u005C\u0022' resolves to '\"'] [note: no \x] [e.g. vText = \u0022hello\u0022 resolves to vText = "hello"] JavaScript: "\x22" + "\u221A" + "\u{1D11E}" Kotlin: "\u0022" + "\u221A" + "\uD834\uDD1E" [note: no \x] PHP: "\x22" . "\u{221A}" . "\u{1D11E}" Python: "\x22" + "\u221A" + "\U0001D11E" R: paste0("\x22", "\u221A", "\U{1D11E}") [note: upper-case 'U': "\U{1D11E}"] [also: "\U0001D11E"] Ruby: "\x22" + "\u221A" + "\u{1D11E}" Rust: "".to_string() + "\x22" + "\u{221A}" + "\u{1D11E}" Scala: "\"" + "\u221A" + "\uD834\uDD1E" [note: '\u0022' within a string causes an error] [note: no \x] Swift: "\u{22}" + "\u{221A}" + "\u{1D11E}" [note: no \x] UFL: Ord [or StringToInt/StrToInt][codepoint at start of string][i.e. string to char to int][i.e. string to first char to int] AutoHotkey: Ord [e.g. (codepoints 0-1114111): Ord(vText)] C++: ___ [e.g. read 1 byte: (int)(unsigned char)vText[0]] [note: cast to int so that std::cout prints chars as integers not symbols] [note: std::string stores strings as bytes (UTF-8)] C#: ConvertToUtf32 [e.g. (codepoints 0-1114111): Char.ConvertToUtf32(vText, 0)] Crystal: ord [e.g. (codepoints 0-1114111): vText[0].ord] Excel: UNICODE [e.g. (codepoints 0-1114111): UNICODE(A1)] [note: UNICODE (Excel 2013)] [WARNING: CODE only handles codepoints 0-127 (ASCII) reliably] Excel VBA: AscW [e.g. (codepoints 0-65535): AscW(vText) And 65535] [WARNING: codepoints 32768-65535 return -32768 to -1, i.e. a signed short (Int16) rather than an unsigned short (UInt16), use 'And 65535' (bitwise and) to fix this (to correct negative return values and leave positive values unchanged)] Go: ___ [can use (codepoints 0-1114111): []rune(vText)[0]] [also (UTF-8 byte): vText[0]] Java: codePointAt [e.g. (codepoints 0-1114111): vText.codePointAt(0)] JavaScript: codePointAt [e.g. (codepoints 0-1114111): vText.codePointAt()] [also (codepoints 0-65535): vText.charCodeAt()] Kotlin: codePointAt [e.g. (codepoints 0-1114111): vText.codePointAt(0)] [also (codepoints 0-65535): vText.single().code] [deprecated: vText.toInt()] PHP: mb_ord [e.g. (codepoints 0-1114111): mb_ord($vText)] [WARNING: ord only handles codepoints 0-255] Python: ord [e.g. (codepoints 0-1114111): ord(vText)] R: utf8ToInt [e.g. (codepoints 0-1114111): utf8ToInt(vText)] [note: if a multi-char string, returns a vector] Ruby: ord [e.g. (codepoints 0-1114111): vText.ord] Rust: ___ [can use (codepoints 0-1114111): u32::from(vText.chars().nth(0).unwrap()) as i32] Scala: codePointAt [e.g. (codepoints 0-1114111): vText.codePointAt(0)] Swift: ___ [can use (codepoints 0-1114111): Array(vText)[0].unicodeScalars.first!.value] [also (codepoints 0-1114111): Int(UnicodeScalar(String(vText.prefix(1)))!.value)] UFL: ChrAt [or CharAt][nth character (as string) (a substring)][WARNING: languages may use 0-based/1-based string indexes][i.e. string to char to string][see also: SubStr/StrSplitChars] AutoHotkey: ___ [can use (UTF-16 short, 1-based): SubStr(vText, vPos, 1)] [can use (codepoint, 1-based): RegExReplace(vText, "^.{" (vPos-1) "}(.).*$", "$1")] C++: ___ [e.g. (UTF-8 byte): std::string("") + vText[vPos]] C#: ___ [e.g. (UTF-16 short): "" + vText[vPos]] Crystal: ___ [can use (codepoint): vText[vPos].to_s] [also: vText.chars[vPos].to_s] Excel: ___ [can use (UTF-16 short, 1-based): MID(A1,vPos,1)] Excel VBA: ___ [can use (UTF-16 short, 1-based): Mid(vText, vPos, 1)] Go: ___ [can use (codepoint): string([]rune(vText)[vPos])] [also (codepoint): strings.Split(vText, "")[vPos]] [also (UTF-8 byte): string(vText[vPos])] Java: charAt [e.g. (UTF-16 short): "" + vText.charAt(vPos)] JavaScript: ___ [can use (codepoint): [...vText][vPos]] [note: 'Strings are iterated by Unicode code points.'] [can use (UTF-16 short): vText.charAt(vPos)] [note (charAt): can omit pos to get the first char] Kotlin: get [e.g. (UTF-16 short): "" + vText.get(vPos)] PHP: ___ [can use (codepoint): mb_substr($vText, $vPos, 1)] [can use (UTF-8 byte): $vText[$vPos]] [WARNING: strings accept negative indexes relative to end, arrays don't (because PHP arrays are really maps, and negative indexes are valid keys)] Python: ___ [can use (codepoint): vText[vPos]] R: ___ [can use (codepoint): substr(vText, vPos, vPos)] Ruby: ___ [can use (codepoint): vText[vPos]] [also: vText.chars[vPos]] Rust: ___ [can use (codepoint): vText.chars().nth(vPos).unwrap().to_string()] Scala: charAt [e.g. (UTF-16 short): "" + vText.charAt(vPos)] Swift: ___ [can use (codepoint): Array(vText)[vPos]] [can use (codepoint): vText[vText.index(vText.startIndex, offsetBy:vPos)]] UFL: OrdAt [codepoint of nth character][WARNING: languages may use 0-based/1-based string indexes][i.e. string to char to int] AutoHotkey: ___ [can use: Ord(SubStr(vText, vPos, 2))] [WARNING: uses UTF-16 shorts, position may be partway through a char (returns low surrogate)] C++: ___ C#: ConvertToUtf32 [e.g. Char.ConvertToUtf32(vText, vPos)] [WARNING: uses UTF-16 shorts, position may be partway through a char (throws)] Crystal: codepoint_at [e.g. vText.codepoint_at(vPos)] [can use: vText[vPos].ord] [also: vText.codepoints[vPos]] Excel: ___ Excel VBA: ___ Go: ___ [can use: []rune(vText)[vPos]] [also (UTF-8 byte): vText[vPos]] Java: codePointAt [e.g. vText.codePointAt(vPos)] [WARNING: uses UTF-16 shorts, position may be partway through a char (returns low surrogate)] JavaScript: codePointAt [e.g. vText.codePointAt(vPos)] [WARNING: uses UTF-16 shorts, position may be partway through a char (returns low surrogate)] Kotlin: codePointAt [e.g. vText.codePointAt(vPos)] [WARNING: uses UTF-16 shorts, position may be partway through a char (returns low surrogate)] PHP: ___ [can use: mb_ord(mb_substr($vText, $vPos, 1))] [WARNING: ord only handles codepoints 0-255] Python: ___ [can use: ord(vText[vPos])] R: ___ [can use: utf8ToInt(substr(vText, vPos, vPos))] Ruby: ___ [can use: vText[vPos].ord] [also: vText.codepoints[vPos]] Rust: ___ [can use: vText.chars().nth(vPos).unwrap() as i32] Scala: codePointAt [e.g. vText.codePointAt(vPos)] [WARNING: uses UTF-16 shorts, if position halfway through a surrogate pair returns low surrogate (if position at start of surrogate pair, returns codepoint)] Swift: ___ [can use: Array(vText)[vPos].unicodeScalars.first!.value] UFL: StrRept [or StrRepeat][repeat a string n times] AutoHotkey: ___ [can use: StrReplace(Format("{:" vCount "}", ""), " ", vText)] C++: ___ [can use (to repeat a character): std::string(vCount, vChar)] [can use: += repeatedly] C#: ___ [can use: String.Concat(Enumerable.Repeat(vText, vCount))] [also (slower): (new String('_', vCount)).Replace("_", vText)] [requires (Repeat): using System.Linq] Crystal: ___ [can use (* operator): vText * vCount] [WARNING: mathematical operator used on strings] Excel: REPT [e.g. REPT(vText,vCount)] Excel VBA: WorksheetFunction.Rept [e.g. WorksheetFunction.Rept(vText, vCount)] [also: Space and Replace] [also: String and Replace] [also: String to repeat a character] Go: strings.Repeat [e.g. strings.Repeat(vText, vCount)] Java: repeat [e.g. vText.repeat(vCount)] JavaScript: repeat [e.g. vText.repeat(vCount)] Kotlin: repeat [e.g. vText.repeat(vCount)] PHP: str_repeat [e.g. str_repeat($vText, $vCount)] Python: ___ [can use (* operator): vText * vCount] [WARNING: mathematical operator used on strings] R: strrep [e.g. strrep(vText, vCount)] Ruby: ___ [can use (* operator): vText * vCount] [WARNING: mathematical operator used on strings] Rust: repeat [e.g. vText.repeat(vCount)] Scala: repeat [e.g. vText.repeat(vCount)] Swift: String [e.g. String(repeating:vText, count:vCount)] UFL: StrCount [count occurrences of substring][WARNING: languages may use 0-based/1-based string indexes][see also: StrContains/InStr/InStrNth/StrSplit] AutoHotkey: ___ [can use (StrReplace's Count parameter): StrReplace(vText, vNeedle, "", 1, &vCount)] [note: 1 to specify case sensitive] [WARNING (StrReplace): case-insensitive by default] [also (string split): vCount := StrSplit(vText, vNeedle).Length - 1] C++: ___ C#: ___ [can use (string split): vCount = vText.Split(vNeedle).Length - 1] Crystal: ___ [can use: vCount = vText.scan(vNeedle).size] [WARNING: vText.count(vNeedle) counts chars, not substrings] Excel: ___ [can use: =(LEN(A1)-LEN(SUBSTITUTE(A1,B1,"")))/LEN(B1)] [can use (for 1-char needles): =LEN(A1)-LEN(SUBSTITUTE(A1,B1,""))] Excel VBA: ___ [can use: vCount = (Len(vText) - Len(Replace(vText, vNeedle, ""))) / Len(vNeedle)] Go: strings.Count [e.g. vCount := strings.Count(vText, vNeedle)] Java: ___ [can use: vCount = (vText.length() - vText.replace(vNeedle, "").length()) / vNeedle.length()] [WARNING: split() takes a RegEx needle, and omits a trailing blank string, workaround: use endsWith()] JavaScript: ___ [can use (string split): vCount = vText.split(vNeedle).length - 1] Kotlin: ___ [can use (string split): vCount = vText.split(vNeedle).size - 1] PHP: mb_substr_count [e.g. vCount = mb_substr_count($vText, $vNeedle)] [also (uses bytes, and has offset/length parameters): substr_count] Python: str.count [e.g. vCount = vText.count(vNeedle)] R: ___ [can use: vCount = ifelse(oMatch[[1]][1]!=-1, length(oMatch[[1]]), 0)] [beforehand (RegEx needle): oMatch = gregexpr(vNeedle, vText)] Ruby: ___ [can use: vCount = vText.scan(vNeedle).count] [WARNING: vText.count(vNeedle) counts chars, not substrings] Rust: ___ [can use: vCount = vText.matches(vNeedle).count())] Scala: ___ [can use: vCount = (vText.length - vText.replace(vNeedle, "").length) / vNeedle.length] [WARNING: split() takes a RegEx needle, and omits a trailing blank string, workaround: use endsWith()] Swift: ___ [can use: vCount = (vText.count - vText.replacingOccurrences(of:vNeedle, with:"").count) / vNeedle.count] [requires: import Foundation] [WARNING: split() omits leading/trailing blank strings, workaround: use hasPrefix() and hasSuffix()] UFL: StrCountCasIns [count occurrences of substring][WARNING: languages may use 0-based/1-based string indexes][see also: StrContains/InStr/StrSplit] AutoHotkey: ___ [can use: StrReplace's Count parameter] [WARNING: case-insensitive by default] C++: ___ C#: ___ Crystal: ___ [can use: vText.scan(Regex.new(vNeedle, Regex::CompileOptions::IGNORE_CASE)).size] [WARNING: vText.count(vNeedle) counts chars, not substrings] Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ [can use: vCount = ifelse(oMatch[[1]][1]!=-1, length(oMatch[[1]]), 0)] [beforehand (RegEx needle): oMatch = gregexpr(vNeedle, vText, ignore.case=TRUE)] Ruby: ___ [can use: vText.scan(Regexp.new(vNeedle, "i")).count] [WARNING: vText.count(vNeedle) counts chars, not substrings] Rust: ___ Scala: ___ Swift: ___ UFL: StrLen [string length][note: using the language's default unit of length] AutoHotkey: StrLen [e.g. StrLen(vText)] [unit: UTF-16 shorts] C++: size [e.g. vText.size()] [also: vText.length()] [also: strlen/wcslen] [unit: UTF-8 bytes] [note: 'Both string::size and string::length are synonyms and return the same value.'] C#: Length [e.g. vText.Length] [unit: UTF-16 shorts] Crystal: size [e.g. vText.size] [unit: codepoints] Excel: LEN [e.g. LEN(A1)] [unit: UTF-16 shorts] Excel VBA: Len [e.g. Len(vText)] [unit: UTF-16 shorts] Go: len [e.g. len(vText)] [unit: UTF-8 bytes] Java: length [e.g. vText.length()] [unit: UTF-16 shorts] [WARNING: vText.length() requires parentheses, unlike oArray.length] JavaScript: length [e.g. vText.length] [unit: UTF-16 shorts] Kotlin: length [e.g. vText.length] [also: vText.count()] [unit: UTF-16 shorts] PHP: strlen [e.g. strlen($vText)] [unit: UTF-8 bytes] Python: len [e.g. len(vText)] [unit: codepoints] [note: Python 2 and 3 differ] R: nchar [e.g. nchar(vText)] [unit: codepoints] Ruby: length [e.g. vText.length] [also: vText.size] [unit (both): codepoints] Rust: len [e.g. vText.len()] [unit: UTF-8 bytes] Scala: length [e.g. vText.length] [also: vText.length()] [unit: UTF-16 shorts] Swift: count [e.g. vText.count] [unit: codepoints] UFL: (StrLenDemo) [e.g. square root (a BMP char), e.g. treble clef (a surrogate pair)] AutoHotkey: StrLen("√"), StrLen("𝄞") [output: 1,2] [unit: UTF-16 shorts] C++: std::string("√").length(), std::string("𝄞").length() [output: 3,4] [unit: UTF-8 bytes] C#: "√".Length, "𝄞".Length [output: 1,2] [unit: UTF-16 shorts] Crystal: "√".size, "𝄞".size [output: 1,1] [unit: codepoints] Excel: √, 𝄞 [output: 1,2] [unit: UTF-16 shorts] Excel VBA: Len(ChrW(8730)), Len(ChrW(55348) & ChrW(56606)) [output: 1,2] [unit: UTF-16 shorts] Go: len("√"), len("𝄞") [output: 3,4] [unit: UTF-8 bytes] Java: "√".length(), "𝄞".length() [output: 1,2] [unit: UTF-16 shorts] JavaScript: "√".length, "𝄞".length [output: 1,2] [unit: UTF-16 shorts] Kotlin: "√".length, "𝄞".length [output: 1,2] [unit: UTF-16 shorts] [note: vText.count(): same results] PHP: strlen("√"), strlen("𝄞") [output: 3,4] [unit: UTF-8 bytes] Python: len("√"), len("𝄞") [output: 1,1] [unit: codepoints] R: nchar("√"), nchar("𝄞") [output: 1,1] [unit: codepoints] Ruby: "√".length, "𝄞".length [output: 1,1] [unit: codepoints] Rust: "√".len(), "𝄞".len() [output: 3,4] [unit: UTF-8 bytes] Scala: "√".length, "𝄞".length [output: 1,2] [unit: UTF-16 shorts] Swift: "√".count, "𝄞".count [output: 1,1] [unit: codepoints] UFL: StrSizeUtf8 [size of string in bytes (UTF-8 encoded)] AutoHotkey: ___ [can use: StrPut(vText, "UTF-8")-1] [note: StrPut returns the size in bytes including a null character] C++: ___ [can use: vText.size()] [also: std::string(vText).size()] [also: length()] C#: ___ [can use: Encoding.UTF8.GetBytes(vText).Length] Crystal: bytesize [e.g. vText.bytesize] Excel: ___ Excel VBA: ___ Go: len [e.g. len(vText)] Java: ___ [can use: vText.getBytes().length] JavaScript: [e.g. new TextEncoder().encode(vText).length] Kotlin: ___ [can use: vText.toByteArray().size] PHP: strlen [e.g. strlen($vText)] Python: ___ [can use: len(vText.encode("utf-8")] R: nchar [e.g. nchar(vText, "bytes")] Ruby: bytesize [e.g. vText.bytesize] Rust: len [e.g. vText.len()] Scala: ___ [can use: vText.getBytes.length] Swift: ___ [can use: vText.utf8.count] UFL: StrLenUtf16 [size of string in (2-byte) shorts (UTF-16 encoded)][note: double this value to get 'StrSizeUtf16', size in bytes] AutoHotkey: StrLen [e.g. StrLen(vText)] C++: ___ [can use: for (const auto& vChar : vText) vLen += ((vChar&0xC0)!=0x80) + ((vChar&0xF8)==0xF0)] [beforehand: int vLen = 0] [also: vLen = std::accumulate(vText.begin(), vText.end(), 0, [](int vAcc, int vChar) {return vAcc+((vChar&0xC0)!=0x80)+((vChar&0xF8)==0xF0);})] [requires (accumulate): #include <numeric>] [note: +1 if byte doesn't start with 0b10, +1 if byte doesn't start with 0b11110] C#: Length [e.g. vText.Length] Crystal: ___ [can use: vText.encode("UTF16LE").bytesize / 2] [WARNING (encode): 'UTF16' prepends a 2-byte BOM ('UTF16LE' doesn't)] Excel: LEN [e.g. LEN(A1)] Excel VBA: Len [e.g. Len(vText)] Go: ___ [can use: len(utf16.Encode([]rune(vText)))] [requires: import "unicode/utf16"] Java: length [e.g. vText.length()] [WARNING: vText.length() requires parentheses, unlike oArray.length] JavaScript: length [e.g. vText.length] Kotlin: length [e.g. vText.length] [also: vText.count()] PHP: ___ [can use: strlen(mb_convert_encoding($vText, "UTF-16"))/2] Python: ___ [can use: len(vText.encode("utf-16-le"))/2] [WARNING (encode): 'utf-16' prepends a 2-byte BOM ('utf-16-le' doesn't)] R: ___ [can use: nchar(vText) + sum(utf8ToInt(vText)>0xFFFF)] [also: length(iconv(vText, to="UTF-16LE", toRaw=TRUE)[[1]])/2] [WARNING (iconv): 'UTF-16' prepends a 2-byte BOM ('UTF-16LE' doesn't)] Ruby: ___ [can use: vText.encode(Encoding::UTF_16LE).bytesize / 2] [WARNING (encode): 'UTF_16' prepends a 2-byte BOM ('UTF_16LE' doesn't)] Rust: ___ [can use: vText.encode_utf16().count()] Scala: length [e.g. vText.length] Swift: ___ [can use: vText.utf16.count] UFL: StrLenCodepoints [or StrLenUtf32][note: quadruple this value to get 'StrSizeUtf32', size in bytes] AutoHotkey: ___ [can use: RegExReplace(vText, "s).",, &vLen)] [note: AHK v1: drop the '&'] C++: ___ [can use: for (const auto& vChar : vText) vLen += ((vChar&0xC0)!=0x80)] [beforehand: int vLen = 0] [also: vLen = std::accumulate(vText.begin(), vText.end(), 0, [](int vAcc, int vChar) {return vAcc+((vChar&0xC0)!=0x80);})] [requires (accumulate): #include <numeric>] [note: +1 if byte doesn't start with 0b10] C#: ___ [can use: Encoding.UTF32.GetBytes(vText).Length/4] Crystal: size [e.g. vText.size] Excel: ___ Excel VBA: ___ Go: ___ [can use: len([]rune(vText))] Java: codePointCount [e.g. vText.codePointCount(0, vText.length())] JavaScript: ___ [can use: [...vText].length] [note: 'Strings are iterated by Unicode code points.'] Kotlin: codePointCount [e.g. vText.codePointCount(0, vText.length)] PHP: ___ [can use: strlen(mb_convert_encoding($vText, "UTF-32"))/4)] [also: mb_strlen($vText)] Python: ___ [can use: len(vText)] R: nchar [e.g. nchar(vText)] Ruby: length [e.g. vText.length] [also: vText.size] Rust: ___ [can use: vText.chars().count()] Scala: codePointCount [e.g. vText.codePointCount(0, vText.length)] Swift: ___ [can use: vText.count] UFL: StrGetCapacity [get string capacity][in bytes, unless stated][see also: Array.GetCapacity] AutoHotkey: VarSetStrCapacity [note: in UTF-16 shorts] [e.g. vCapacity := VarSetStrCapacity(&vText)] [note: VarSetStrCapacity can *get* and set the capacity] C++: capacity [e.g. vCapacity = vText.capacity()] C#: ___ [note: StringBuilder: vCapacity = oSB.Capacity] [requires: using System.Text] Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ [note: strings.Builder: vCapacity = oSB.Cap()] Java: ___ [note: StringBuilder: vCapacity = oSB.capacity()] JavaScript: ___ Kotlin: ___ [note: StringBuilder: vCapacity = oSB.capacity()] PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: capacity [e.g. vCapacity = vText.capacity()] Scala: ___ [note: StringBuilder: vCapacity = oSB.capacity] Swift: ___ UFL: StrSetCapacity [set string capacity (or request a minimum capacity, i.e. set a capacity greater than or equal to the request)][in bytes, unless stated][see also: Array.SetCapacity] AutoHotkey: VarSetStrCapacity [note: in UTF-16 shorts] [e.g. VarSetStrCapacity(&vText, vCapacity)] [WARNING: makes the string blank] C++: reserve [e.g. vText.reserve(vCapacity)] [also: vText.shrink_to_fit()] C#: ___ [note: StringBuilder: oSB.Capacity = vCapacity] [requires: using System.Text] Crystal: new [e.g. new string: vText = String.new(vCapacity){|v| {vCapacity,vCapacity}}] Excel: ___ Excel VBA: ___ Go: ___ [note: strings.Builder: oSB.Grow(vCapacityToAdd)] [WARNING: value is capacity to *add*, not the future total] Java: ___ [note: StringBuilder: oSB.ensureCapacity(vCapacity)] [also: StringBuilder: oSB.trimToSize()] JavaScript: ___ Kotlin: ___ [note: StringBuilder: oSB.ensureCapacity(vCapacity)] [also: StringBuilder: oSB.trimToSize()] PHP: ___ Python: ___ R: ___ Ruby: new [e.g. new string: vText = String.new(capacity:vCapacity)] [e.g. modify string: vText = String.new(vText, capacity:vCapacity)] Rust: reserve [WARNING: value is capacity to *add*, not the future total] [e.g. add: vText.reserve(vCapacityToAdd)] [e.g. set total: vText.reserve(vCapacity-vText.len())] [also: reserve_exact/shrink_to_fit/shrink_to/truncate] Scala: ___ [note: StringBuilder: oSB.ensureCapacity(vCapacity)] Swift: ___ UFL: StrReplace [replace 'before' string with 'after' string (no RegEx), all occurrences, there may be an option to replace the first n occurrences][WARNING: languages may use 0-based/1-based string indexes][see also: RegExReplace] AutoHotkey: StrReplace [WARNING: case-insensitive by default] [e.g. vTextNew := StrReplace(vText, vBefore, vAfter, 1)] [WARNING: different param order, AHK v1/v2] C++: ___ [can use: repeated find() and replace()] [also (case-insensitive): repeated find() and std::search() with custom char comparator function] C#: Replace [e.g. vTextNew = vText.Replace(vBefore, vAfter)] Crystal: gsub [e.g. vTextNew = vText.gsub(vBefore, vAfter)] Excel: SUBSTITUTE [e.g. SUBSTITUTE(A1,vBefore,vAfter)] [note: case-sensitive] Excel VBA: Replace [e.g. vTextNew = Replace(vText, vBefore, vAfter)] Go: strings.ReplaceAll [e.g. vTextNew := strings.ReplaceAll(vText, vBefore, vAfter)] [also: strings.Replace has a mandatory param 'n', a max number of replacements to do] Java: replace [e.g. vTextNew = vText.replace(vBefore, vAfter)] [WARNING: replaceAll/replaceFirst treat the 'before' string as a RegEx needle] [WARNING: replace/replaceAll both replace all occurrences] JavaScript: replaceAll [e.g. vTextNew = vText.replaceAll(vBefore, vAfter)] Kotlin: replace [e.g. vTextNew = vText.replace(vBefore, vAfter)] PHP: str_replace [e.g. $vTextNew = str_replace($vBefore, $vAfter, $vText)] Python: str.replace [e.g. vTextNew = vText.replace(vBefore, vAfter)] R: ___ [can use (RegEx needle): vTextNew = gsub(vBefore, vAfter, vText)] Ruby: gsub [e.g. vTextNew = vText.gsub(vBefore, vAfter)] [WARNING: replace() modifies the string, it assigns a new value, e.g. vText.replace(vValue)] Rust: replace [e.g. vTextNew = vText.replace(vBefore, vAfter)] Scala: replace [e.g. vTextNew = vText.replace(vBefore, vAfter)] [WARNING: replaceAll/replaceFirst treat the 'before' string as a RegEx needle] [WARNING: replace/replaceAll both replace all occurrences] Swift: replacingOccurrences [e.g. vText.replacingOccurrences(of:vBefore, with:vAfter)] [requires: import Foundation] UFL: StrReplaceCasIns [replace 'before' string with 'after' string (no RegEx), all occurrences, there may be an option to replace the first n occurrences][WARNING: languages may use 0-based/1-based string indexes][workaround: RegExReplace][see also: RegExReplace] AutoHotkey: StrReplace [WARNING: case-insensitive by default] [e.g. case-insensitive: vTextNew := StrReplace(vText, vBefore, vAfter)] [WARNING: different param order, AHK v1/v2] C++: ___ [can use: repeated find() and replace()] [also (case-insensitive): repeated find() and std::search() with custom char comparator function] C#: Replace [e.g. vTextNew = vText.Replace(vBefore, vAfter, StringComparison.OrdinalIgnoreCase)] Crystal: ___ Excel: ___ Excel VBA: Replace [e.g. case-insensitive: vTextNew = Replace(vText, vBefore, vAfter, , , 1)] Go: ___ Java: ___ JavaScript: ___ Kotlin: replace [e.g. vTextNew = vText.replace(vBefore, vAfter, true)] PHP: str_ireplace [e.g. $vTextNew = str_ireplace($vBefore, $vAfter, $vText)] [WARNING: only ASCII chars are replaced case-insensitively, other chars are replaced case-sensitively] Python: ___ R: ___ [can use (RegEx needle): vTextNew = gsub(vBefore, vAfter, vText, ignore.case=TRUE)] Ruby: ___ Rust: ___ Scala: ___ Swift: replacingOccurrences [e.g. vText.replacingOccurrences(of:vBefore, with:vAfter, options:.caseInsensitive)] [requires: import Foundation] UFL: StrReplaceMax [or StrReplaceN][replace 'before' string with 'after' string (no RegEx), the first n occurrences][WARNING: languages may use 0-based/1-based string indexes][see also: RegExReplace] AutoHotkey: StrReplace [WARNING: case-insensitive by default] [e.g. case-sensitive: vTextNew := StrReplace(vText, vBefore, vAfter, 1,, vLimit)] [WARNING: different param order, AHK v1/v2] C++: ___ C#: ___ Crystal: ___ Excel: ___ [can use (replace one instance, the nth instance): SUBSTITUTE(A1,vBefore,vAfter,vIndex)] [note: case-sensitive] [WARNING: can use multiple nested SUBSTITUTE calls with index set to 1, but avoid if 'after' text contains 'before' text] Excel VBA: Replace [e.g. vTextNew = Replace(vText, vBefore, vAfter, , vLimit)] Go: strings.Replace [e.g. vTextNew := strings.Replace(vText, vBefore, vAfter, vLimit)] Java: ___ [can use (replace first instance, RegEx needle): vTextNew = vText.replaceFirst(vBefore, vAfter)] [WARNING: can use multiple replaceFirst calls, but avoid if 'after' text contains 'before' text] [WARNING: replaceAll/replaceFirst treat the 'before' string as a RegEx needle] [WARNING: replace/replaceAll both replace all occurrences] JavaScript: ___ [can use: vTemp = 0; vTextNew = vText.replace(new RegExp(vBefore, "g"), vMatch=>vTemp++<vLimit?vAfter:vMatch);] Kotlin: ___ [can use (replace first instance, string): vTextNew = vText.replaceFirst(vBefore, vAfter)] [WARNING: can use multiple replaceFirst calls, but avoid if 'after' text contains 'before' text] [note: replace() replaces all occurrences] PHP: ___ Python: str.replace [e.g. vTextNew = vText.replace(vBefore, vAfter, vLimit)] R: ___ Ruby: ___ Rust: replacen [e.g. vTextNew = vText.replacen(vBefore, vAfter, vLimit)] Scala: ___ [can use (replace first instance, RegEx needle): vTextNew = vText.replaceFirst(vBefore, vAfter)] [WARNING: can use multiple replaceFirst calls, but avoid if 'after' text contains 'before' text] [WARNING: replaceAll/replaceFirst treat the 'before' string as a RegEx needle] [WARNING: replace/replaceAll both replace all occurrences] Swift: ___ UFL: StrSplit [string to array (split by delimiters)][note: can accept a multi-char string as a separator unless stated][note: see StrSplitChars re. languages where blank string *and* blank delim sometimes returns 1 or more strings][see also: StrSplitChars/StrSplitMax] AutoHotkey: StrSplit [e.g. oArray := StrSplit(vText, vSep)] [note: blank delimiter: 1 output string per char] C++: ___ [can use: repeated find and substr] [also (single-char separator only): std::stringstream and getline] [WARNING: getline ignores a blank line after the last separator] [requires (stringstream): #include <sstream>] C#: Split [e.g. oArray = vText.Split(vSep)] [note: blank delimiter: 1 output string (entire string)] [note: C# 9 (.NET 5): accepts a string delimiter, before that, only a char] Crystal: split [e.g. oArray = vText.split(vSep)] [note: blank delimiter: 1 output string per char] Excel: TEXTSPLIT [note: TEXTSPLIT (Excel 365)] Excel VBA: Split [e.g. oArray = Split(vText, vSep)] [note: blank delimiter: 1 output string (entire string)] Go: strings.Split [e.g. oArray := strings.Split(vText, vSep)] [note: blank delimiter: 1 output string per char] [also (maintain the separators): strings.SplitAfter] [also (limit to n splits): strings.SplitN/strings.SplitAfterN] [also: strings.FieldsFunc] Java: split [WARNING: splits based on RegEx, not a literal string] [e.g. oArray = vText.split(vSep, -1)] [note: blank delimiter: 1 output string per char] [WARNING: limit param: omitted or 0 to omit trailing blank strings, -1 to maintain them] JavaScript: split [e.g. oArray = vText.split(vSep)] [note: blank delimiter: 1 output string per char] Kotlin: split [WARNING: blank delimiter: 1 output string per char, with 2 (leading/trailing) blank strings] [e.g. oArray = vText.split(vSep).toTypedArray()] PHP: explode [WARNING: str_split splits into chunks of size n, not by delimiter] [e.g. $oArray = explode($vSep, $vText)] [note: blank delimiter: throws] Python: str.split [e.g. oArray = vText.split(vSep)] [note: use list to split a string to a list of 1-char strings] [note: str.rsplit returns the last n items if maxsplit is specified] [note: blank delimiter: throws] R: strsplit [WARNING: splits based on RegEx, use fixed=TRUE to split based on a literal string] [e.g. oVec = strsplit(vText, vSep)[[1]]] [e.g. oVec = unlist(strsplit(vText, vSep))] [note: blank delimiter: 1 output string per char] [WARNING: omits 1 trailing blank string (if multiple trailing blank strings, only omits the last one)] Ruby: split [e.g. oArray = vText.split(vSep, -1)] [note: blank delimiter: 1 output string per char] [WARNING: limit param: omitted or 0 to omit trailing blank strings, -1 to maintain them] Rust: split [e.g. oVec: Vec<&str> = vText.split(vSep).collect()] [WARNING: blank delimiter: 1 output string per char, with 2 (leading/trailing) blank strings] [also (limit to n splits): splitn] Scala: split [WARNING: splits based on RegEx, not a literal string] [e.g. oArray = vText.split(vSep, -1)] [note: blank delimiter: 1 output string per char] [WARNING: limit param: omitted or 0 to omit trailing blank strings, -1 to maintain them] Swift: split [e.g. oArray = vText.split(separator:vSep, omittingEmptySubsequences:false).map{String($0)}] [note: blank delimiter: 1 output string per char] [WARNING: omittingEmptySubsequences param: omitted or true to omit all leading/internal/trailing blank strings, false to maintain them] UFL: StrSplitChars [often equivalent to StrChunk(vText, 1)][create an array of strings of length 1][note: splits by codepoints (maintains surrogate pairs) unless stated][WARNING: in some languages, "".split(vSep) returns [""], not []][see also: ChrAt/StrChunk] AutoHotkey: ___ [can use (find a char not in vText first): StrSplit(RegExReplace(vText, "(?<=.)(?=.)", vUnused), vUnused)] [can use: oArray := StrSplit(vText)] [also: StrSplit(vText, "")] [WARNING: StrSplit no/blank separator splits surrogate pairs] [note: split blank string (all approaches): return array length 0] C++: ___ C#: ___ [can use: string[] oArray = Regex.Split(vText, "(?<=.)(?=.)(?![\uDC00-\uDFFF])")] [requires (Regex.Split): using System.Text.RegularExpressions] [also: StringInfo.GetTextElementEnumerator] [also: UTF32Encoding and BitConverter] [also (WARNING: splits surrogate pairs): string[] oArray = vText.Select(v=>v.ToString()).ToArray()] [WARNING: split blank string (Regex.Split): return array length 1] Crystal: split [e.g. oArray = vText.split("")] [also: oArray = vText.chars.map{|v| v.to_s}] [also (char array): oArray = vText.chars] [note: creates a copy] [WARNING: split blank string (split()): return array length 1] Excel: ___ Excel VBA: ___ Go: strings.Split [e.g. oArray := strings.Split(vText, "")] [note: split blank string: return array length 0] Java: ___ [can use: String[] oArray = vText.codePoints().mapToObj(Character::toString).toArray(String[]::new)] [also: vText.split("(?<=.)")] [also (WARNING: splits surrogate pairs): vText.split("")] [WARNING: split blank string (for both approaches using split()): return array length 1] JavaScript: ___ [can use: oArray = [...vText]] [note: 'Strings are iterated by Unicode code points.'] [note: split blank string (split()): return array length 0] [also (WARNING: splits any surrogate pairs): vText.split("")] Kotlin: ___ [can use: oArray = vText.codePoints().mapToObj{Character.toString(it)}.toList().toTypedArray()] [also (WARNING: splits surrogate pairs): vText.chunked(1)] [WARNING: split(): returns blank strings at start and end] [WARNING: split blank string (split()): return array length 2] [also: vText.split("").drop(1).dropLast(1)] [note: split blank string (chunked()): return array length 0] PHP: ___ [can use: $oArray = mb_str_split($vText)] [note: split blank string: return array length 0] [WARNING: str_split (unlike mb_str_split) splits by bytes] Python: ___ [can use: oList = list(vText)] [note: split blank string: return array length 0] R: strsplit [e.g. oVec = strsplit(vText, "")] [note: split blank string: return array length 0] Ruby: chars [e.g. oArray = vText.chars] [note: creates a copy] [also: oArray = vText.split("")] [note: split blank string (split()): return array length 0] Rust: ___ [can use: oVec = vText.chars().map(|v| v.to_string()).collect::<Vec<String>>()] Scala: ___ [can use: vText.codePoints.mapToObj(Character.toString(_)).toArray] [also: vText.split("(?<=.)")] [also (WARNING: splits surrogate pairs): vText.split("")] [note: split blank string (for both approaches using split()): return array length 0 (unlike Java)] Swift: ___ [can use: oArray = Array(vText).map{String($0)}] [note: split blank string: return array length 0] UFL: (StrSplitAZDemo) [create an array of strings of length 1][note: the approaches below work on ASCII chars, but not necessarily all Unicode codepoints] AutoHotkey: oArray := StrSplit("abcdefghijklmnopqrstuvwxyz") C++: ___ [can use: std::string oArray[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}] C#: string[] oArray = "abcdefghijklmnopqrstuvwxyz".Select(v=>v.ToString()).ToArray() Crystal: oArray = "abcdefghijklmnopqrstuvwxyz".split("") Excel: ___ Excel VBA: ___ [can use: oArray = Array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")] Go: oArray := strings.Split("abcdefghijklmnopqrstuvwxyz", "") Java: oArray = "abcdefghijklmnopqrstuvwxyz".split("") JavaScript: oArray = [..."abcdefghijklmnopqrstuvwxyz"] [also: oArray = "abcdefghijklmnopqrstuvwxyz".split("")] Kotlin: oArray = "abcdefghijklmnopqrstuvwxyz".chunked(1) PHP: $oArray = mb_str_split("abcdefghijklmnopqrstuvwxyz") Python: oList = list("abcdefghijklmnopqrstuvwxyz") R: oVec = strsplit("abcdefghijklmnopqrstuvwxyz", "") Ruby: oArray = "abcdefghijklmnopqrstuvwxyz".chars [also: oArray = "abcdefghijklmnopqrstuvwxyz".split("")] Rust: oVec = "abcdefghijklmnopqrstuvwxyz".chars().map(|v| v.to_string()).collect::<Vec<String>>() Scala: oArray = "abcdefghijklmnopqrstuvwxyz".split("") [also: oArray = ('a' to 'z').map(_.toString).toArray] Swift: oArray = Array("abcdefghijklmnopqrstuvwxyz").map{String($0)} UFL: StrSplitNthOrDefault [string split by delimiter, return nth item, or if too few items, return default value][see also: StrSplit/InStrNth/Array.GetOrDefault] AutoHotkey: vValue := (vKey==1) || InStr(vText, vSep,,, vKey-1) ? StrSplit(vText, vSep)[vKey] : vDefault [note: 1-based] C++: ___ C#: vValue = vText.Split(vSep).ElementAtOrDefault(vKey) ?? vDefault [note: if no key is found, ElementAtOrDefault() returns the default value for the type, e.g. null for strings, you can't specify a default value] Crystal: vValue = vText.split(vSep).fetch(vKey, vDefault) Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: vValue = vText.split(vSep)[vKey] ?? vDefault Kotlin: vValue = vText.split(vSep).getOrElse(vKey){vDefault} PHP: $vValue = explode($vSep, $vText)[$vKey] ?? $vDefault Python: vValue = (vText.split(vSep)[vKey:vKey+1]or[vDefault])[0] R: vValue = na.omit(c(strsplit(vText, vSep)[[1]][vKey], vDefault))[1] [note: 1-based] Ruby: vValue = vText.split(vSep).fetch(vKey, vDefault) Rust: ___ Scala: vValue = vText.split(vSep).zipWithIndex.find(e=>e._2==vKey).getOrElse((vDefault, 0))._1 Swift: vValue = vText.split(separator:vSep).enumerated().first{$0.offset==vKey}.map{String($1)} ?? vDefault UFL: StrSplitMax [or StrSplitN][string to array (split by delimiters), maximum n strings, where the nth string is 'the rest'][note: can accept a multi-char string as a separator unless stated][note: see StrSplitChars re. languages where blank string *and* blank delim sometimes returns 1 or more strings][note: below, vMax gives you a maximum n strings, including 'the rest'] AutoHotkey: StrSplit [e.g. oArray := StrSplit(vText, vSep,, vMax)] C++: ___ C#: Split [e.g. oArray = vText.Split(vSep, vMax)] [note: C# 9 (.NET 5): accepts a string delimiter, before that, only a char] Crystal: split [e.g. oArray = vText.split(vSep, vMax)] Excel: ___ Excel VBA: Split [e.g. oArray = Split(vText, vSep, vMax)] Go: strings.SplitN [e.g. oArray := strings.SplitN(vText, vSep, vMax)] [also (maintain the separators): strings.SplitAfterN] [also: strings.FieldsFunc] Java: split [WARNING: splits based on RegEx, not a literal string] [e.g. oArray = vText.split(vSep, vMax)] JavaScript: ___ [WARNING: split with 'limit' param specified: 'Any leftover text is not included in the array at all.' (max n clean items, and never a leftover item)] [can use: oArray = [vText.split(vSep, vMax-1), [vText.split(vSep).slice(vMax-1)].map(v=>v.length?v.join(vSep):[])].flat(2)] Kotlin: split [e.g. oArray = vText.split(vSep, limit=vMax).toTypedArray()] PHP: explode [WARNING: str_split splits into chunks of size n, not by delimiter] [e.g. $oArray = explode($vSep, $vText, $vMax)] Python: str.split [e.g. oArray = vText.split(vSep, vMax-1)] [WARNING: unlike most languages, maxsplit=n can return an array of n+1 items (max n clean items, and a possible leftover item)] [note: str.rsplit returns the last n items if maxsplit is specified] R: ___ Ruby: split [e.g. oArray = vText.split(vSep, vMax)] Rust: split [e.g. oVec: Vec<&str> = vText.splitn(vMax, vSep).collect()] Scala: split [WARNING: splits based on RegEx, not a literal string] [e.g. oArray = vText.split(vSep, vMax)] Swift: split [e.g. oArray = vText.split(separator:vSep, maxSplits:vMax-1, omittingEmptySubsequences:false).map{String($0)}] [WARNING: unlike most languages, maxSplits=n can return an array of n+1 items (max n clean items, and a possible leftover item)] UFL: StrChunk [or StrSplitLen][string to array (split into chunks of n chars)][workaround: RegExReplace and StrSplit][see also: Array.Chunk/RegExReplace] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: chunked PHP: mb_str_split [WARNING: str_split (unlike mb_str_split) splits by bytes (e.g. based on their UTF-8 bytes: mb_chr(8730) becomes 3 chars, mb_chr(119070) becomes 4 chars) (mb_str_split splits based on codepoints)] [WARNING: splits into chunks of size n, not by delimiter] Python: ___ R: ___ [can use: substring(vText, oVec, oVec+(vCount-1))] [beforehand: oVec = seq(1, nchar(vText), vCount)] Ruby: ___ Rust: ___ [can use: oVec = vText.chars().collect::<Vec<char>>().chunks(vCount).map(|v| v.iter().collect::<String>()).collect::<Vec<String>>()] Scala: ___ [can use: oArray = vText.grouped(vCount).toArray] [WARNING: can split surrogate pairs] Swift: ___ UFL: (StrHatch) [add a separator every n chars][see also: RegExReplace/StrChunk/StrJoin] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: chunk_split [WARNING: doesn't split to an array, adds a separator every n chars] [also (add thousands separators): number_format] Python: ___ R: ___ Ruby: ___ Rust: ___ Scala: ___ [can use: vTextNew = vText.grouped(vCount).mkString(vSep)] [WARNING: can split surrogate pairs] Swift: ___ UFL: StrJoin [specify a separator string, and one or more strings (or an array) to join][see also: Array.Join] AutoHotkey: ___ C++: ___ [can use: += repeatedly] [also: note: strcat/wcscat] C#: Join [e.g. String.Join(vSep, vText1, vText2, vText3)] [also: String.Join(vSep, oArray)] Crystal: ___ [can use: oArray.join(vSep)] Excel: TEXTJOIN [e.g. TEXTJOIN(vSep,, vText1, vText2, vText3)] [note: TEXTJOIN (Excel 2016)] Excel VBA: WorksheetFunction.TextJoin [also: Join(oArray, vSep)] Go: ___ [can use: strings.Join(oArray, vSep)] Java: join [e.g. String.join(vSep, vText1, vText2, vText3)] [also: String.join(vSep, oArray)] JavaScript: ___ [can use: oArray.join(vSep)] Kotlin: ___ [can use: oArray.joinToString(vSep)] PHP: ___ [can use: implode($vSep, $oArray)] [also (alias): join($vSep, $oArray)] Python: ___ [can use (str.join): e.g. vSep.join(oList)] [WARNING: can't do: oList.join(vSep)] R: paste [e.g. paste(vText1, vText2, vText3, sep=vSep)] [also: paste(oVec, collapse=vSep)] [also: paste(oVec1, oVec2, sep=vSep1, collapse=vSep2)] Ruby: ___ [can use: oArray.join(vSep)] Rust: ___ [can use: oArray.join(vSep)] Scala: String.join [e.g. String.join(vSep, vText1, vText2, vText3)] [also: oArray.mkString(vSep)] Swift: ___ [can use: oArray.joined(separator:vSep)] UFL: StrContains [see also: StrEquals/StrStarts/StrEnds] AutoHotkey: InStr [e.g. case-sensitive: !!InStr(vText, vNeedle, 1)] [note (InStr): 1-based, returns 0 if no match] [WARNING: case-insensitive by default] C++: ___ C#: Contains [e.g. vText.Contains(vNeedle)] Crystal: includes [e.g. vText.includes?(vNeedle)] Excel: ___ [can use: =IFERROR(FIND(vNeedle,A1)>0,0)] [note: FIND returns #VALUE! error if no match] Excel VBA: InStr [e.g. case-sensitive: vIsMatch = (InStr(1, vText, vNeedle) <> 0)] [note: 1-based, returns 0 if no match] Go: strings.Contains [e.g. strings.Contains(vText, vNeedle)] Java: contains [e.g. vText.contains(vNeedle)] JavaScript: includes [e.g. vText.includes(vNeedle)] Kotlin: contains [e.g. vText.contains(vNeedle)] PHP: str_contains [e.g. str_contains($vText, $vNeedle)] Python: in [e.g. vNeedle in vText] [can use: vIsMatch = (vText.find(vNeedle) != -1)] [inverse: vNeedle not in vText] [note: word order: 'not in' versus 'is not'] R: ___ [can use (RegEx, returns bool(s)): grepl(vNeedle, vText)] Ruby: include [e.g. vText.include?(vNeedle)] Rust: contains [e.g. vText.contains(vNeedle)] Scala: contains [e.g. vText.contains(vNeedle)] Swift: contains [e.g. vText.contains(vNeedle)] UFL: InStr [search left-to-right][WARNING: languages may use 0-based/1-based string indexes][see also: InStrRev/StrContains/RegExMatchIndex] AutoHotkey: InStr [e.g. case-sensitive: vPos := InStr(vText, vNeedle, 1)] [note: 1-based, returns 0 if no match] [WARNING: case-insensitive by default] C++: find [e.g. vPos = vText.find(vNeedle)] [note: returns std::string::npos if no match] [also (case-insensitive, forwards or backwards): std::search with custom char comparator function] [also: strstr/wcsstr] C#: IndexOf [e.g. vPos = vText.IndexOf(vNeedle)] [note: returns -1 if no match] Crystal: index [e.g. vPos = vText.index(vNeedle)] [note: returns nil if no match] Excel: FIND [e.g. FIND(vNeedle,A1)] [note: 1-based, returns #VALUE! error if no match] [note: FIND() is case-sensitive, SEARCH() is case-insensitive] Excel VBA: InStr [e.g. case-sensitive: vPos = InStr(1, vText, vNeedle)] [note: 1-based, returns 0 if no match] Go: strings.Index [e.g. vPos := strings.Index(vText, vNeedle)] [note: returns -1 if no match] Java: indexOf [e.g. vPos = vText.indexOf(vNeedle)] [note: returns -1 if no match] JavaScript: indexOf [e.g. vPos = vText.indexOf(vNeedle)] [note: returns -1 if no match] Kotlin: indexOf [e.g. vPos = vText.indexOf(vNeedle)] [note: returns -1 if no match] PHP: mb_strpos [e.g. $vPos = mb_strpos($vText, $vNeedle)] [also (case-insensitive): mb_stripos] [WARNING: returns false if no match] [also (bytes): strpos, stripos] [note: strpos v. strrpos] Python: str.find [e.g. vPos = vText.find(vNeedle)] [note: returns -1 if no match] [note: str.index throws if no match] R: ___ [can use (RegEx needle): vPos = regexpr(vNeedle, vText)[1]] [note: 1-based, returns -1 if no match] Ruby: index [e.g. vPos = vText.index(vNeedle)] [note: returns nil if no match] Rust: find [e.g. oPosOpt = vText.find(vNeedle)] [e.g. vIsMatch = oPosOpt.is_some()] [e.g. vPos = oPosOpt.unwrap()] [note: offsets are in bytes] Scala: indexOf [e.g. vPos = vText.indexOf(vNeedle)] [note: returns -1 if no match] Swift: range [e.g. vPos = (oRange != nil) ? vText.distance(from:vText.startIndex, to:oRange!.lowerBound) : -1] [beforehand: oRange = vText.range(of:vNeedle)] [requires: import Foundation] UFL: InStrCasIns [search left-to-right][WARNING: languages may use 0-based/1-based string indexes][workaround: RegExMatchIndex][see also: InStrRev/StrContains/RegExMatchIndex] AutoHotkey: InStr [e.g. case-insensitive: vPos := InStr(vText, vNeedle)] [note: 1-based, returns 0 if no match] [WARNING: case-insensitive by default] C++: ___ [also (case-insensitive, forwards or backwards): std::search with custom char comparator function] C#: IndexOf [e.g. vPos = vText.IndexOf(vNeedle, StringComparison.OrdinalIgnoreCase)] [note: returns -1 if no match] Crystal: ___ Excel: SEARCH [e.g. SEARCH(vNeedle,A1)] [note: 1-based, returns #VALUE! error if no match] Excel VBA: InStr [e.g. vPos = InStr(1, vText, vNeedle, 1)] [note: 1-based, returns 0 if no match] Go: ___ Java: ___ JavaScript: ___ Kotlin: indexOf [e.g. case-insensitive: vPos = vText.indexOf(vNeedle, 0, true)] [note: returns -1 if no match] PHP: mb_stripos [e.g. $vPos = mb_stripos($vText, $vNeedle)] [WARNING: returns false if no match] [also (case-insensitive, bytes): stripos] Python: ___ R: ___ [can use (RegEx needle): vPos = regexpr(vNeedle, vText, ignore.case=TRUE)[1]] [note: 1-based, returns -1 if no match] Ruby: ___ Rust: ___ Scala: ___ Swift: range [e.g. vPos = (oRange != nil) ? vText.distance(from:vText.startIndex, to:oRange!.lowerBound) : -1] [beforehand: oRange = vText.range(of:vNeedle, options:.caseInsensitive)] [requires: import Foundation] UFL: InStrRev [search right-to-left][get position of last occurrence of substring][WARNING: languages may use 0-based/1-based string indexes][workaround: RegExMatchAll get last][see also: InStr/StrContains/RegExMatchIndex/RegExMatchAll] AutoHotkey: InStr [e.g. case-sensitive (AHK v2): vPos := InStr(vText, vNeedle, 1,, -1)] [note: 1-based, returns 0 if no match] [WARNING: case-insensitive by default] C++: rfind [e.g. vPos = vText.rfind(vNeedle)] [note: returns std::string::npos if no match] [also (case-insensitive, forwards or backwards): std::search with custom char comparator function] C#: LastIndexOf [e.g. vPos = vText.LastIndexOf(vNeedle)] [note: returns -1 if no match] Crystal: rindex [e.g. vPos = vText.rindex(vNeedle)] [note: returns nil if no match] Excel: ___ [can use (find last): get needle string count (LEN/SUBSTITUTE), replace last needle occurrence with temporary char e.g. CHAR(1) (SUBSTITUTE), find char (FIND) (note: '0+' '+0' put around string count for clarity): =FIND(CHAR(1),SUBSTITUTE(A1,B1,CHAR(1),0+(LEN(A1)-LEN(SUBSTITUTE(A1,B1,"")))/LEN(B1)+0))] [note: 1-based, returns #VALUE! error if no match] Excel VBA: InStrRev [e.g. case-sensitive: vPos = InStrRev(vText, vNeedle)] [note: 1-based, returns 0 if no match] Go: strings.LastIndex [e.g. vPos := strings.LastIndex(vText, vNeedle)] [note: returns -1 if no match] Java: lastIndexOf [e.g. vPos = vText.lastIndexOf(vNeedle)] [note: returns -1 if no match] JavaScript: lastIndexOf [e.g. vPos = vText.lastIndexOf(vNeedle)] [note: returns -1 if no match] Kotlin: lastIndexOf [e.g. vPos = vText.lastIndexOf(vNeedle)] [note: returns -1 if no match] [note: don't confuse with indexOfLast] PHP: mb_strrpos [e.g. $vPos = mb_strrpos($vText, $vNeedle)] [also (case-insensitive): mb_strripos] [WARNING: returns false if no match] [also (bytes): strrpos, strripos] [note: strpos v. strrpos] Python: str.rfind [e.g. vPos = vText.rfind(vNeedle)] [note: returns -1 if no match] [note: str.rindex throws if no match] R: ___ Ruby: rindex [e.g. vPos = vText.rindex(vNeedle)] [note: returns nil if no match] Rust: rfind [e.g. oPosOpt = vText.rfind(vNeedle)] [e.g. vIsMatch = oPosOpt.is_some()] [e.g. vPos = oPosOpt.unwrap()] [note: offsets are in bytes] Scala: lastIndexOf [note: returns -1 if no match] Swift: ___ UFL: InStrNth [get position of nth occurrence of substring][also: check if a string appears at least n times, 'string count at least'][workaround: some search functions return indexes for all matches][see also: RegExMatchIndex/RegExMatchAll/StrSplit/StrCount] AutoHotkey: InStr [e.g. vPos := InStr(vText, vNeedle, 1,, vOcc)] [note: 1-based vPos, 1-based vOcc (occurrence), returns 0 if no match] [note: 3rd param sets case sensitivity] C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ [can use (RegEx, 3rd occurrence of 'abc', -1 if no match): vPos = vText.search(/(?<=(abc.*?){2})abc/)] Kotlin: ___ [can use (RegEx, findAll): vPos = Regex(vNeedle).findAll(vText).map{it.range.start}.toList().getOrElse(vOcc-1){-1}] [note: 0-based vPos, 1-based vOcc (occurrence), returns -1 if no match] PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: ___ [can use: match_indices] Scala: ___ Swift: ___ [can use (RegEx): matches] UFL: StrStarts [or StrStartsWith][see also: StrEquals/StrContains/StrEnds] AutoHotkey: ___ C++: starts_with [e.g. vText.starts_with(vNeedle)] [also: strncmp/wcsncmp] C#: StartsWith [e.g. vText.StartsWith(vNeedle)] Crystal: starts_with [e.g. vText.starts_with?(vNeedle)] Excel: ___ Excel VBA: ___ Go: strings.HasPrefix [e.g. strings.HasPrefix(vText, vNeedle)] Java: startsWith [e.g. vText.startsWith(vNeedle)] JavaScript: startsWith [e.g. vText.startsWith(vNeedle)] Kotlin: startsWith [e.g. vText.startsWith(vNeedle)] PHP: str_starts_with [e.g. str_starts_with($vText, $vNeedle)] Python: str.startswith [e.g. vText.startswith(vNeedle)] R: startsWith [e.g. startsWith(vText, vNeedle)] Ruby: start_with [e.g. vText.start_with?(vNeedle)] Rust: starts_with [e.g. vText.starts_with(vNeedle)] Scala: startsWith [e.g. vText.startsWith(vNeedle)] Swift: hasPrefix [e.g. vText.hasPrefix(vNeedle)] UFL: StrEnds [or StrEndsWith][see also: StrEquals/StrContains/StrStarts] AutoHotkey: ___ C++: ends_with [e.g. vText.ends_with(vNeedle)] C#: EndsWith [e.g. vText.EndsWith(vNeedle)] Crystal: ends_with [e.g. vText.ends_with?(vNeedle)] Excel: ___ Excel VBA: ___ Go: strings.HasSuffix [e.g. strings.HasSuffix(vText, vNeedle)] Java: endsWith [e.g. vText.endsWith(vNeedle)] JavaScript: endsWith [e.g. vText.endsWith(vNeedle)] Kotlin: endsWith [e.g. vText.endsWith(vNeedle)] PHP: str_ends_with [e.g. str_ends_with($vText, $vNeedle)] Python: str.endswith [e.g. vText.endswith(vNeedle)] R: endsWith [e.g. endsWith(vText, vNeedle)] Ruby: end_with [e.g. vText.end_with?(vNeedle)] Rust: ends_with [e.g. vText.ends_with(vNeedle)] Scala: endsWith [e.g. vText.endsWith(vNeedle)] Swift: hasSuffix [e.g. vText.hasSuffix(vNeedle)] UFL: RegExNew [or StrToRegEx][string to RegEx object][note: some languages use 'RegEx', some use 'RegExp'] AutoHotkey: ___ [note: AutoHotkey stores RegEx needles as strings] C++: std::regex [e.g. creates a variable: std::regex oRegEx(vNeedle)] [requires: #include <regex>] C#: ___ [note: C# stores RegEx needles as strings] [requires: using System.Text.RegularExpressions] Crystal: Regex.new [e.g. oRegEx = Regex.new(vNeedle)] Excel: ___ Excel VBA: ___ [can use: Set oRegEx = CreateObject("VBScript.RegExp")] [afterwards: oRegEx.Pattern = vNeedle] Go: regexp.Compile [e.g. oRegEx, vErr := regexp.Compile(vNeedle)] Java: Pattern.compile [e.g. Pattern oRegEx = Pattern.compile(vNeedle)] [requires: import java.util.regex.Pattern] JavaScript: RegExp [e.g. oRegEx = new RegExp(vNeedle)] [e.g. oRegEx = new RegExp(vNeedle, vFlags)] Kotlin: Regex [e.g. oRegEx = Regex(vNeedle)] PHP: ___ [note: PHP stores RegEx needles as strings (with leading and trailing slashes)] Python: re.compile [e.g. oRegEx = re.compile(vNeedle)] [requires: import re] R: ___ [note: R stores RegEx needles as strings] Ruby: Regexp.new [e.g. oRegEx = Regexp.new(vNeedle)] Rust: Regex::new [e.g. oRegEx = Regex::new(vNeedle).unwrap()] [requires: use regex::Regex] Scala: r [e.g. oRegEx = vNeedle.r] [also: oRegEx = Regex(vNeedle)] [requires (Regex): import scala.util.matching.Regex] [note: can omit the import, and write it longhand: scala.util.matching.Regex(vNeedle)] Swift: Regex [e.g. oRegEx = try Regex(vNeedle)] UFL: RegExEscape [or StrEscape][add escape characters to treat all characters literally, rather than treat some as metacharacters] AutoHotkey: ___ [note: AutoHotkey supports \Q and \E] C++: ___ C#: Regex.Escape Crystal: Regex.escape [e.g. Regex.escape(vText)] [also: vText.dump] [also: vText.inspect] Excel: ___ Excel VBA: ___ Go: regexp.QuoteMeta [e.g. regexp.QuoteMeta(vText)] Java: Pattern.quote [e.g. Pattern.quote(vText)] [requires: import java.util.regex.Pattern] JavaScript: ___ Kotlin: Regex.escape PHP: preg_quote Python: re.escape R: ___ [note: all (or almost all) the RegEx functions have a 'fixed' i.e. literal option] [note: R supports \Q and \E] Ruby: Regexp.escape [e.g. Regexp.escape(vText)] [also: vText.dump] [also: vText.inspect] [also (alias): Regexp.quote] Rust: regex::escape [e.g. regex::escape(vText)] Scala: Regex.quote [e.g. Regex.quote(vText)] [requires: import scala.util.matching.Regex] [note: can omit the import, and write it longhand: scala.util.matching.Regex.quote(vText)] Swift: ___ UFL: RegExMatchIndex [get the offset of the first match, and perhaps get the text of any substrings][WARNING: languages may use 0-based/1-based string indexes] AutoHotkey: RegExMatch [e.g. vPos := RegExMatch(vText, vNeedle)] [also (~=): vPos := vText ~= vNeedle] [note: 1-based, returns 0 if no match] C++: std::regex_search [e.g. if a match found (if vIsMatch): vPos = oMatch.prefix().length()] [beforehand: std::smatch oMatch] [beforehand: vIsMatch = std::regex_search(vText, oMatch, oRegEx)] [also (whole-string match): std::regex_match] C#: Match [e.g. if a match found (if oMatch.Success): vPos = oMatch.Index] [beforehand: oMatch = Regex.Match(vText, vNeedle)] [WARNING: Regex.Match(vText, vNeedle).Index returns 0 if no match, and 0 if the start of the string matches] Crystal: index [e.g. vPos = vText.index(oRegEx)] [also: vPos = vText =~ oRegEx] [note: returns nil if no match] Excel: ___ [can use: very limited functionality: COUNTIF and COUNTIFS accept strings with wildcards] Excel VBA: ___ [can use: if a match found: vPos = oRegEx.Execute(vText)(0).FirstIndex] [beforehand: Set oRegEx = CreateObject("VBScript.RegExp"): oRegEx.Pattern = vNeedle] [beforehand (also): If oRegEx.Test(vText)] Go: FindStringIndex [e.g. oPos := oRegEx.FindStringIndex(vText)] [afterwards: vTextNew := vText[oPos[0]:oPos[1]])] [note: returns nil if no match] Java: find [e.g. if a match found: vPos = oMatcher.start()] [beforehand (also): vIsMatch = oMatcher.find()] [beforehand: Matcher oMatcher = oRegEx.matcher(vText)] [requires: import java.util.regex.Matcher] JavaScript: search [e.g. vPos = vText.search(oRegEx)] [note: returns -1 if no match] Kotlin: find [e.g. if a match found: vPos = oMatch.range.start] [beforehand (returns null if no match): oMatch = oRegEx.find(vText)] [also: containsMatchIn/contains] PHP: preg_match [e.g. preg_match($vNeedle, $vText, $oMatch, PREG_OFFSET_CAPTURE)] [afterwards (returns offset of first match, else null if no match): $vPos = $oMatch[0][1]] [also: mb_ereg_match] [note: 'preg' = Perl, 'ereg' = POSIX] Python: re.search [e.g. vPos = oRegEx.search(vText).start()] [note: search() returns None if no match] R: regexpr [e.g. vPos = regexpr(vNeedle, vText)[1]] [note: 1-based, returns -1 if no match] Ruby: index [e.g. vPos = vText.index(oRegEx)] [also: vPos = vText =~ oRegEx] [note: returns nil if no match] Rust: find [e.g. oPosOpt = oRegEx.find(vText)] [e.g. vIsMatch = oPosOpt.is_some()] [e.g. vPos = oPosOpt.unwrap()] [note: offsets are in bytes] Scala: findAllIn [e.g. if a match found: vPos = oMatchIter.start] [beforehand (also): vIsMatch = oMatchIter.hasNext] [beforehand: oMatchIter = oRegEx.findAllIn(vText)] Swift: firstMatch [e.g. vPos = (oMatch != nil) ? vText.distance(from:vText.startIndex, to:oMatch!.range.lowerBound) : -1] [beforehand: oMatch = try oRegEx.firstMatch(in:vText)] UFL: (RegExMatchIndexDemo) [RegEx match demo: return 0-based offset of first match, or return -1 if no match] AutoHotkey: RegExMatch [e.g. vPos := -1 + RegExMatch(vText, vNeedle)] [note: -1 to convert 1-based to 0-based] C++: std::regex_search [e.g. vPos = oMatch.prefix().length() - !vIsMatch] [beforehand: std::smatch oMatch] [beforehand: vIsMatch = std::regex_search(vText, oMatch, oRegEx)] [also (whole-string match): std::regex_match] C#: Match [e.g. vPos = oMatch.Index - (oMatch.Success ? 0 : 1)] [beforehand: oMatch = Regex.Match(vText, vNeedle)] [WARNING: Regex.Match(vText, vNeedle).Index returns 0 if no match, and 0 if the start of the string matches] Crystal: index [e.g. vPos = vText.index(oRegEx) || -1] [note: 0 is truthy in Crystal, so is maintained] Excel: ___ Excel VBA: ___ [can use: If oRegEx.Test(vText) Then vPos = oRegEx.Execute(vText)(0).FirstIndex Else vPos = -1] [beforehand: Set oRegEx = CreateObject("VBScript.RegExp"): oRegEx.Pattern = vNeedle] Go: ___ [note: Go lacks a ternary operator] Java: find [e.g. vPos = oMatcher.find() ? oMatcher.start() : -1] [beforehand: Matcher oMatcher = oRegEx.matcher(vText)] [requires: import java.util.regex.Matcher] JavaScript: search [e.g. vPos = vText.search(oRegEx)] [note: returns -1 if no match] Kotlin: find [e.g. vPos = oRegEx.find(vText)?.range?.start ?: -1] PHP: preg_match [e.g. $vPos = $oMatch[0][1] ?? -1] [beforehand: preg_match($vNeedle, $vText, $oMatch, PREG_OFFSET_CAPTURE)] Python: re.search [e.g. vPos = next((v.start() for v in [oRegEx.search(vText)] if v!=None), -1)] R: ___ [can use: vPos = max(regexpr(vNeedle, vText)[1]-1, -1)] [note: -1 to convert 1-based to 0-based] [note: -1 applied to -1 (no match) gives -2, max makes it -1 again (the other values are unaffected by max)] Ruby: index [e.g. vPos = vText.index(oRegEx) || -1] [note: 0 is truthy in Ruby, so is maintained] Rust: find [e.g. vPos = oRegEx.find(vText).map_or(-1, |v| v.start() as i32)] [note: offsets are in bytes] Scala: findAllIn [e.g. vPos = if(oMatchIter.hasNext) oMatchIter.start else -1] [beforehand: oMatchIter = oRegEx.findAllIn(vText)] Swift: firstMatch [e.g. vPos = (oMatch != nil) ? vText.distance(from:vText.startIndex, to:oMatch!.range.lowerBound) : -1] [beforehand: oMatch = try oRegEx.firstMatch(in:vText)] UFL: RegExMatchBool [return a boolean, whether the RegEx contains a match or not][see also: StrIsAlnumRegExDemo] AutoHotkey: RegExMatch [e.g. vIsMatch := !!RegExMatch(vText, vNeedle)] [also (~=): vIsMatch := !!(vText ~= vNeedle)] [note: 1-based, returns 0 if no match] C++: std::regex_search [e.g. vIsMatch = std::regex_search(vText, oMatch, oRegEx)] [beforehand: std::smatch oMatch] [also (whole-string match): std::regex_match] C#: Match [e.g. vIsMatch = oMatch.Success] [beforehand: oMatch = Regex.Match(vText, vNeedle)] Crystal: matches [e.g. vIsMatch = oRegEx.matches?(vText)] [also: vIsMatch = (vText.index(oRegEx) != nil)] [also: vIsMatch = ((vText =~ oRegEx) != nil)] Excel: ___ Excel VBA: Test [e.g. vIsMatch = oRegEx.Test(vText)] [beforehand: Set oRegEx = CreateObject("VBScript.RegExp"): oRegEx.Pattern = vNeedle] Go: MatchString [e.g. vIsMatch := oRegEx.MatchString(vText)] Java: find [e.g. vIsMatch = oRegEx.matcher(vText).find()] [also (whole-string match): matches] JavaScript: test [e.g. oRegEx.test(vText)] Kotlin: containsMatchIn [e.g. vIsMatch = oRegEx.containsMatchIn(vText)] [also: vIsMatch = (oRegEx.find(vText) != null)] PHP: preg_match [e.g. $vIsMatch = !!preg_match($vNeedle, $vText)] [also: mb_ereg_match] [note: 'preg' = Perl, 'ereg' = POSIX] Python: re.search [e.g. vIsMatch = (oRegEx.search(vText) != None)] R: regexpr [e.g. vIsMatch = (regexpr(vNeedle, vText)[1] != -1)] Ruby: match [e.g. vIsMatch = oRegEx.match?(vText)] [also: vIsMatch = (vText.index(oRegEx) != nil)] [also: vIsMatch = ((vText =~ oRegEx) != nil)] Rust: is_match [e.g. vIsMatch = oRegEx.is_match(vText)] [also: vIsMatch = oRegEx.find(vText).is_some()] Scala: findFirstIn [e.g. oRegEx.findFirstIn(vText).isDefined] Swift: firstMatch [e.g. vIsMatch = (oMatch != nil)] [beforehand: oMatch = try oRegEx.firstMatch(in:vText)] UFL: (RegExMatchWhole) [return a boolean, whether the RegEx matches the whole string or not][workaround: use '^' and '$' anchors] AutoHotkey: ___ C++: std::regex_match [e.g. vIsMatch = std::regex_match(vText, oMatch, oRegEx)] [beforehand: std::smatch oMatch] [note: std::regex_match (whole-string match) cf. std::regex_search] C#: ___ Crystal: ___ [can use (with '^'/'$' anchors): vText.matches?(oRegEx)] Excel: ___ Excel VBA: ___ Go: ___ Java: matches [note: whole-string match] JavaScript: ___ Kotlin: matches [e.g. "abc".matches(Regex("..."))] [also: Regex("...").matchEntire("abc")] [note (both): whole-string match] PHP: ___ Python: re.fullmatch [e.g. vIsMatch = (re.fullmatch("...", "abc") != None)] R: ___ Ruby: ___ [can use (with '^'/'$' anchors): vText.match?(oRegEx)] Rust: ___ Scala: ___ [can use (with '^'/'$' anchors): oRegEx.findFirstIn(vText).isDefined] Swift: wholeMatch UFL: RegExMatchAll [or RegExFindAll][find all matches][e.g. return an array (of indexes/lengths, perhaps substrings)][WARNING: languages may use 0-based/1-based string indexes] AutoHotkey: ___ C++: std::regex_iterator [also: repeated std::regex_search] C#: Matches Crystal: scan [e.g. vText.scan(oRegEx).map{|v| v.to_s}] Excel: ___ Excel VBA: ___ [can use: CreateObject("VBScript.RegExp") and Execute] Go: ___ [can use: FindStringIndex repeatedly] Java: ___ [can use: find repeatedly] JavaScript: matchAll [e.g. oArray = [...vText.matchAll(oRegEx)]] [also: oArray = vText.match(oRegEx) || []] [note: match returns a string array (or null if no matches)] [note: matchAll returns an iterator, key 0 contains a string, property 'index' contains a position] [note: for matchAll, the RegEx must use the global flag] [note: equivalent to match (where the RegEx uses the global flag): [...vText.matchAll(oRegEx)].map(v=>v[0])] [also (where the RegEx uses the global flag, lastIndex is the position after the last match, where repeatedly using 'test' iterates): oRegEx.test(vText); vPos = oRegEx.lastIndex] Kotlin: findAll PHP: preg_match_all Python: re.findall [also: re.split] R: gregexpr [e.g. get match offsets (-1 if no matches): unlist(gregexpr(vNeedle, vText))] Ruby: scan [e.g. vText.scan(oRegEx)] Rust: find_iter Scala: ___ [can use: findAllIn once, and then hasNext/next repeatedly] [note: 'start' to get position, 'next' to get a matching string and advance by 1 item] Swift: matches UFL: RegExReplace [replace all matches][perhaps with an option to replace the first n matches] AutoHotkey: RegExReplace C++: std::regex_replace C#: Regex.Replace Crystal: gsub [e.g. vTextNew = vText.gsub(oRegEx, vAfter)] Excel: ___ Excel VBA: ___ [can use: CreateObject("VBScript.RegExp") and Replace] Go: ReplaceAllString [e.g. vTextNew := oRegEx.ReplaceAllString(vText, vAfter)] [also: ReplaceAllStringFunc/ReplaceAllLiteralString] Java: replaceAll JavaScript: replace Kotlin: replace PHP: preg_replace [also: mb_ereg_replace] [note: 'preg' = Perl, 'ereg' = POSIX] Python: re.sub R: gsub [e.g. vTextNew = gsub(vBefore, vAfter, vText)] Ruby: gsub [e.g. vTextNew = vText.gsub(oRegEx, vAfter)] Rust: replace_all [e.g. vTextNew = oRegEx.replace_all(vText, vAfter)] [beforehand: oRegEx = Regex::new(vNeedle).unwrap()] Scala: replaceAllIn [e.g. oRegEx.replaceAllIn(vText, vAfter)] Swift: replacingOccurrences [also: stringByReplacingMatchesInString] UFL: SubStr [substring using pos/count][WARNING: languages may use 0-based/1-based string indexes][WARNING: if languages use UTF-8 bytes or UTF-16 shorts, a substring may split within a char] AutoHotkey: SubStr [e.g. (UTF-16 shorts): vTextNew := SubStr(vText, vPos, vCount)] [note: 1-based] C++: substr [e.g. (UTF-8 bytes): vTextNew = vText.substr(vPos, vCount)] [WARNING: substr uses bytes, so can frequently split within a char] C#: Substring [e.g. (UTF-16 shorts): vTextNew = vText.Substring(vPos, vCount)] Crystal: ___ [can use (codepoints): vTextNew = vText[vPos...vPos+vCount]] Excel: MID [e.g. (UTF-16 shorts): MID(A1,vPos,vCount)] Excel VBA: Mid [e.g. (UTF-16 shorts): vTextNew = Mid(vText, vPos, vCount)] [note: unlike Excel sheet function, can omit count parameter] Go: ___ [can use (codepoints): vTextNew := string([]rune(vText)[vPos : vPos+vCount])] Java: ___ [can use (UTF-16 shorts): vTextNew = vText.substring(vPos, vPos+vCount)] JavaScript: ___ [can use (UTF-16 shorts): vTextNew = vText.slice(vPos, vPos+vCount)] [deprecated: substr(vPos, vCount)] [note: don't confuse with substring(vPos1, vPos2)] Kotlin: ___ [can use (UTF-16 shorts): vTextNew = vText.slice(vPos..<vPos+vCount)] PHP: mb_substr [e.g. (codepoints): $vTextNew = mb_substr($vText, $vPos, $vCount)] [WARNING: substr uses bytes, so can frequently split within a char] Python: ___ [can use (codepoints): vTextNew = vText[vPos:vPos+vCount]] R: ___ [can use (codepoints): vTextNew = substr(vText, vPos, vPos+vCount-1)] [note: 1-based] [note: substr/substring: equivalent, except substring lets you omit the endpoint] [note: the endpoint is inclusive] Ruby: slice [e.g. vTextNew = vText.slice(vPos, vCount)] [also: vText[vPos...vPos+vCount]] Rust: ___ [can use (codepoints): vTextNew: String = vText.chars().skip(vPos).take(vCount).collect()] Scala: ___ [can use (UTF-16 shorts): vTextNew = vText.substring(vPos, vPos+vCount)] Swift: ___ [can use (codepoints): vTextNew = String(Array(vText)[vPos..<vPos+vCount])] UFL: (StrSliceExc) [substring using pos1/pos2 (exclusive end)][WARNING: languages may use 0-based/1-based string indexes][note: all approaches below return a string] AutoHotkey: ___ [can use: vTextNew := SubStr(vText, vPos1, vPos2-vPos1)] C++: ___ [can use: vTextNew = vText.substr(vPos1, vPos2-vPos1)] C#: ___ [can use: vTextNew = vText.Substring(vPos1, vPos2-vPos1)] Crystal: ___ [can use: vTextNew = vText[vPos1...vPos2]] Excel: ___ [can use: MID(A1,vPos1,vPos2-vPos1)] Excel VBA: ___ [can use: vTextNew = Mid(vText, vPos1, vPos2 - vPos1)] Go: ___ [can use: vTextNew := string([]rune(vText)[vPos1:vPos2])] Java: substring [e.g. vTextNew = vText.substring(vPos1, vPos2)] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: slice [e.g. vTextNew = vText.slice(vPos1, vPos2)] [also: substring(vPos1, vPos2)] [note: don't confuse with (deprecated) substr(vPos, vCount)] Kotlin: slice [e.g. vTextNew = vText.slice(vPos1..<vPos2)] [also: substring] [deprecated: subSequence] PHP: ___ [can use: $vTextNew = mb_substr($vText, $vPos1, $vPos2-$vPos1)] Python: ___ [can use: vTextNew = vText[vPos1:vPos2]] [note: vText[start:end:step]] R: ___ [can use: vTextNew = substr(vText, vPos1, vPos2-1)] Ruby: slice [e.g. vTextNew = vText.slice(vPos1...vPos2)] [also: vText[vPos1...vPos2]] Rust: ___ [can use: vTextNew: String = vText.chars().skip(vPos1).take(vPos2-vPos1).collect()] [also: vText.get(vPos1..vPos2).unwrap().to_string()] Scala: substring [e.g. vTextNew = vText.substring(vPos1, vPos2)] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] Swift: ___ [can use: vTextNew = String(vText[vText.index(vText.startIndex, offsetBy:vPos1)..<vText.index(vText.startIndex, offsetBy:vPos2)])] [also: vTextNew = String(Array(vText)[vPos1..<vPos2])] [also: vTextNew = String(vText.dropFirst(vPos1).dropLast(vText.count-vPos2))] [also: vTextNew = String(vText.dropFirst(vPos1).prefix(vPos2-vPos1))] UFL: (StrSliceInc) [substring using pos1/pos2 (inclusive end)][WARNING: languages may use 0-based/1-based string indexes][note: all approaches below return a string] AutoHotkey: ___ [can use: vTextNew := SubStr(vText, vPos1, vPos2-vPos1+1)] C++: ___ [can use: vTextNew = vText.substr(vPos1, vPos2-vPos1+1)] C#: ___ [can use: vTextNew = vText.Substring(vPos1, vPos2-vPos1+1)] Crystal: ___ [can use: vTextNew = vText[vPos1..vPos2]] Excel: ___ [can use: MID(A1,vPos1,vPos2-vPos1+1)] Excel VBA: ___ [can use: vTextNew = Mid(vText, vPos1, vPos2 - vPos1 + 1)] Go: ___ [can use: vTextNew := string([]rune(vText)[vPos1 : vPos2+1])] Java: ___ [can use: vTextNew = vText.substring(vPos1, vPos2+1)] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: ___ [can use: vTextNew = vText.slice(vPos1, vPos2+1)] Kotlin: slice [e.g. vTextNew = vText.slice(vPos1..vPos2)] PHP: ___ [can use: $vTextNew = mb_substr($vText, $vPos1, $vPos2-$vPos1+1)] Python: ___ [can use: vTextNew = vText[vPos1:vPos2+1]] R: ___ [can use: vTextNew = substr(vText, vPos1, vPos2)] Ruby: slice [e.g. vTextNew = vText.slice(vPos1..vPos2)] [also: vText[vPos1..vPos2]] Rust: ___ [can use: vTextNew: String = vText.chars().skip(vPos1).take(vPos2-vPos1+1).collect()] [also: vText.get(vPos1..=vPos2).unwrap().to_string()] Scala: ___ [can use: vTextNew = vText.substring(vPos1, vPos2+1)] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] Swift: ___ [can use: vTextNew = String(Array(vText)[vPos1...vPos2])] [also: vTextNew = String(vText.dropFirst(vPos1).dropLast(vText.count-vPos2-1))] [also: vTextNew = String(vText.dropFirst(vPos1).prefix(vPos2-vPos1+1))] UFL: (StrLeft) [or StrTakeLeft/StrTakeFirst][get the first n chars][see also: StrFirst] AutoHotkey: ___ [can use: vTextNew := SubStr(vText, 1, vCount)] C++: ___ [can use: vTextNew = vText.substr(0, vCount)] C#: ___ [can use: vTextNew = vText.Substring(0, Math.Min(vCount, vText.Length))] Crystal: ___ [can use: vTextNew = vText[...vCount]] Excel: LEFT [e.g. LEFT(A1,vCount)] [note: omit Count same as Count 1] Excel VBA: Left [e.g. vTextNew = Left(vText, vCount)] [note: can't omit Count] Go: ___ [can use: vTextNew := string([]rune(vText)[:vCount])] Java: ___ [can use: vTextNew = vText.substring(0, Math.min(vCount, vText.length()))] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: ___ [can use: vTextNew = vText.slice(0, vCount)] [also: substring] [note: don't confuse with (deprecated) substr(vPos, vCount)] Kotlin: take [e.g. vTextNew = vText.take(vCount)] PHP: ___ [can use: $vTextNew = mb_substr($vText, 0, $vCount)] Python: ___ [can use: vTextNew = vText[:vCount]] R: ___ [can use: vTextNew = substr(vText, 1, vCount)] [also (display width): vTextNew = strtrim(vText, vCount)] Ruby: slice [e.g. vTextNew = vText.slice(0, vCount)] [also: vText.slice(...vCount)] [also: vText[...vCount]] Rust: ___ [can use: vTextNew: String = vText.chars().take(vCount).collect()] Scala: ___ [can use: vTextNew = vText.substring(0, math.min(vCount, vText.length))] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] Swift: prefix [e.g. vTextNew = String(vText.prefix(vCount))] UFL: (StrRight) [or StrTakeRight/StrTakeLast][get the last n chars][see also: StrLast] AutoHotkey: ___ [can use: vTextNew := SubStr(vText, -vCount)] [note: AHK v1: SubStr(vText, -vCount+1)] C++: ___ [can use: vTextNew = vText.substr(vCount<vText.size()?vText.size()-vCount:0)] [also: vText.substr(std::max<int>(vText.size()-vCount, 0))] [requires (max): #include <algorithm>] C#: ___ [can use: vTextNew = vText.Substring(Math.Max(vText.Length-vCount, 0))] Crystal: ___ [can use: vTextNew = vText[-vCount..]] Excel: RIGHT [e.g. RIGHT(A1,vCount)] [note: omit Count same as Count 1] Excel VBA: Right [e.g. vTextNew = Right(vText, vCount)] [note: can't omit Count] Go: ___ [can use: vTextNew := string([]rune(vText)[len([]rune(vText))-vCount:])] Java: ___ [can use: vTextNew = vText.substring(Math.max(vText.length()-vCount, 0))] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: ___ [can use: vTextNew = vText.slice(-vCount)] [also: substring] Kotlin: takeLast [e.g. vTextNew = vText.takeLast(vCount)] PHP: ___ [can use: $vTextNew = mb_substr($vText, -$vCount)] Python: ___ [can use: vTextNew = vText[-vCount:]] R: ___ [can use: vTextNew = substring(vText, nchar(vText)-vCount+1)] [note: substr/substring: equivalent, except substring lets you omit the endpoint] Ruby: slice [e.g. vTextNew = vText.slice(-vCount..)] [also: vText[-vCount..]] Rust: ___ [can use: vTextNew: String = vText.chars().skip(vText.chars().count()-vCount).collect()] Scala: ___ [can use: vTextNew = vText.substring(math.max(vText.length-vCount, 0))] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] Swift: suffix [e.g. vTextNew = String(vText.suffix(vCount))] UFL: (StrDropLeft) [or StrDropFirst][remove the first n chars][see also: StrUpperFirstOnly] AutoHotkey: ___ [can use: vTextNew := SubStr(vText, vCount+1)] C++: ___ [can use: vTextNew = vText.substr(vCount)] C#: ___ [can use: vTextNew = vText.Remove(0, vCount)] [also: vTextNew = vText.Substring(vCount)] Crystal: ___ [can use: vTextNew = vText[vCount..]] Excel: ___ [can use: drop left 10: =MID(A1,11,LEN(A1))] [e.g. drop left 10: =REPLACE(A1,1,10,"")] [e.g. drop left 10: =IFERROR(RIGHT(A1,LEN(A1)-10),"")] Excel VBA: ___ [can use: vTextNew = Mid(vText, vCount + 1)] Go: ___ [can use: vTextNew := string([]rune(vText)[vCount:])] Java: ___ [can use: vTextNew = vText.substring(vCount, vText.length())] JavaScript: ___ [can use: vTextNew = vText.slice(vCount)] [also: substring] Kotlin: drop [e.g. vTextNew = vText.drop(vCount)] PHP: ___ [can use: $vTextNew = mb_substr($vText, $vCount)] Python: ___ [can use: vTextNew = vText[vCount:]] R: ___ [can use: vTextNew = substring(vText, vCount+1)] [note: substr/substring: equivalent, except substring lets you omit the endpoint] Ruby: slice [e.g. vTextNew = vText.slice(vCount..)] [also: vText[vCount..]] Rust: ___ [can use: vTextNew: String = vText.chars().skip(vCount).collect()] Scala: ___ [can use: vTextNew = vText.substring(vCount, vText.length)] Swift: dropFirst [e.g. vTextNew = String(vText.dropFirst(vCount))] UFL: (StrDropRight) [or StrDropLast][remove the last n chars] AutoHotkey: ___ [can use: vTextNew := SubStr(vText, 1, -vCount)] C++: ___ [can use: vTextNew = vText.substr(0, vText.length()-vCount)] C#: ___ [can use: vTextNew = vText.Remove(vText.Length-vCount)] [also: vTextNew = vText.Substring(0, vText.Length-vCount)] Crystal: ___ [can use: vTextNew = vText[...-vCount]] Excel: ___ [can use: drop right 10: =IFERROR(LEFT(A1,LEN(A1)-10),"")] [e.g. drop right 10: =IFERROR(MID(A1,1,LEN(A1)-10),"")] Excel VBA: ___ [can use: vTextNew = Mid(vText, 1, Len(vText) - vCount)] Go: ___ [can use: vTextNew := string([]rune(vText)[:len([]rune(vText))-vCount])] Java: ___ [can use: vTextNew = vText.substring(0, vText.length()-vCount)] JavaScript: ___ [can use: vTextNew = vText.slice(0, -vCount)] [also: substring] Kotlin: dropLast [e.g. vTextNew = vText.dropLast(vCount)] PHP: ___ [can use: $vTextNew = mb_substr($vText, 0, -$vCount)] Python: ___ [can use: vTextNew = vText[:-vCount]] R: ___ [can use: vTextNew = substr(vText, 1, nchar(vText)-vCount)] Ruby: slice [e.g. vTextNew = vText.slice(...-vCount)] [also: vText[...-vCount]] Rust: ___ [can use: vTextNew: String = vText.chars().take(vText.chars().count()-vCount).collect()] Scala: ___ [can use: vTextNew = vText.substring(0, vText.length-vCount)] Swift: dropLast [e.g. vTextNew = String(vText.dropLast(vCount))] UFL: (StrDropBothEnds) [or StrDropLeftAndRight/StrDropFirstAndLast][drop the first n1 chars, and the last n2 chars] AutoHotkey: ___ [can use: vTextNew := SubStr(vText, vCount1+1, -vCount2)] C++: ___ [can use: vTextNew = vText.substr(vCount1, vText.length()-vCount1-vCount2)] C#: ___ [can use: vTextNew = vText.Substring(vCount1, vText.Length-vCount1-vCount2)] Crystal: ___ [can use: vTextNew = vText[vCount1...-vCount2]] Excel: ___ [can use: MID(A1,vCount1+1,LEN(A1)-vCount1-vCount2)] Excel VBA: ___ [can use: vTextNew = Mid(vText, vCount1 + 1, Len(vText) - vCount1 - vCount2)] Go: ___ [can use: vTextNew := string([]rune(vText)[vCount1 : len([]rune(vText))-vCount2])] Java: ___ [can use: vTextNew = vText.substring(vCount1, vText.length()-vCount2)] JavaScript: ___ [can use: vTextNew = vText.slice(vCount1, -vCount2)] Kotlin: ___ [can use: vTextNew = vText.drop(vCount1).dropLast(vCount2)] PHP: ___ [can use: $vTextNew = mb_substr($vText, $vCount1, -$vCount2)] Python: ___ [can use: vTextNew = vText[vCount1:-vCount2]] R: ___ [can use: vTextNew = substr(vText, vCount1+1, nchar(vText)-vCount2)] Ruby: slice [e.g. vTextNew = vText.slice(vCount1...-vCount2)] [also: vText[vCount1...-vCount2]] Rust: ___ [can use: vTextNew: String = vText.chars().skip(vCount1).take(vText.chars().count()-vCount1-vCount2).collect()] Scala: ___ [can use: vTextNew = vText.substring(vCount1, vText.length-vCount2)] Swift: ___ [can use: vTextNew = String(vText.dropFirst(vCount1).dropLast(vCount2))] UFL: (StrFirst) [get the first char as a string][see also: StrLeft] AutoHotkey: ___ [can use (UTF-16 shorts): vTextNew := SubStr(vText, 1, 1)] [also (codepoints): vTextNew := RegExReplace(vText, ".\K.*")] C++: ___ [can use (UTF-8 bytes): vTextNew = vText.substr(0, 1)] [also (UTF-8 bytes): vTextNew = std::string("") + vText[0]] C#: ___ [can use (UTF-16 shorts): vTextNew = vText.Substring(0, 1)] [also (UTF-16 shorts): vTextNew = "" + vText[0]] [also (UTF-16 shorts): vTextNew = "" + vText.First()] [requires (First): using System.Linq] Crystal: ___ [can use (codepoints): vTextNew = vText[0].to_s] [can use (codepoints): vTextNew = vText[0..0]] Excel: LEFT [e.g. (UTF-16 shorts): LEFT(A1)] [also: LEFT(A1,1)] Excel VBA: Left [e.g. (UTF-16 shorts): vTextNew = Left(vText, 1)] [note: can't omit Count] Go: ___ [can use (codepoints): vTextNew := string([]rune(vText)[0])] Java: ___ [can use (UTF-16 shorts): vTextNew = "" + vText.charAt(0)] [can use (UTF-16 shorts): vTextNew = vText.substring(0, 1)] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: ___ [can use (codepoints): vTextNew = [...vText][0]] [also (UTF-16 shorts): vTextNew = vText[0]] [also (UTF-16 shorts): vTextNew = vText.charAt()] [also (UTF-16 shorts): vTextNew = vText.slice(0, 1)] [also: substring] [note: don't confuse with (deprecated) substr(vPos, 1)] Kotlin: take [e.g. (UTF-16 shorts): vTextNew = vText.take(1)] [also (UTF-16 shorts): vTextNew = vText[0].toString()] [also (UTF-16 shorts): vTextNew = vText.first().toString()] PHP: ___ [can use (codepoints): $vTextNew = mb_substr($vText, 0, 1)] [also (UTF-8 bytes): $vTextNew = $vText[0]] Python: ___ [can use (codepoints): vTextNew = vText[0]] R: ___ [can use (codepoints): vTextNew = substr(vText, 1, 1)] [also (codepoints): vTextNew = strsplit(vText, "")[[1]][1]] [also (codepoints): vTextNew = unlist(strsplit(vText, ""))[1]] [note: substring also works] [also (codepoints, display width): vTextNew = strtrim(vText, 1)] Ruby: ___ [can use (codepoints): vTextNew = vText[0]] [also (codepoints): vTextNew = vText.slice(0)] [also (codepoints): vTextNew = vText.slice(0, 1)] [WARNING: slice(0) gets first char, not all chars] [WARNING: slice(index) versus slice(start, length)] Rust: ___ [can use: vTextNew: String = vText.chars().take(1).collect()] [also: vTextNew = format!("{}", vText.chars().next().unwrap())] [also (modifies a string, requires a mutable string, not an &str): vTextNew = vText.remove(0).to_string()] Scala: ___ [can use (UTF-16 shorts): vTextNew = "" + vText.charAt(0)] [can use (UTF-16 shorts): vTextNew = vText.substring(0, 1)] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] Swift: first [e.g. (codepoints): vTextNew = String(vText.first!)] [also (codepoints): vTextNew = String(vText.prefix(1))] UFL: (StrLast) [get the last char as a string][see also: StrRight] AutoHotkey: ___ [can use (UTF-16 shorts): vTextNew := SubStr(vText, -1)] [note: AHK v1: SubStr(vText, 0)] [also (codepoints): vTextNew := RegExReplace(vText, "^(.*)(?=.$)")] C++: ___ [can use (UTF-8 bytes): vTextNew = vText.substr(vText.size()-1)] [also (UTF-8 bytes): vTextNew = std::string("") + vText[vText.size()-1]] C#: ___ [can use (UTF-16 shorts): vTextNew = vText.Substring(vText.Length-1)] [also (UTF-16 shorts): vTextNew = "" + vText[vText.Length-1]] [also (UTF-16 shorts): vTextNew = "" + vText.Last()] [requires (Last): using System.Linq] Crystal: ___ [can use (codepoints): vTextNew = vText[-1].to_s] [also (codepoints): vTextNew = vText[-1..-1]] [also (codepoints): vTextNew = vText[vText.size-1].to_s] Excel: RIGHT [e.g. (UTF-16 shorts): RIGHT(A1)] [also: RIGHT(A1,1)] Excel VBA: Right [e.g. (UTF-16 shorts): vTextNew = Right(vText, 1)] [note: can't omit Count] Go: ___ [can use (codepoints): vTextNew := string([]rune(vText)[len([]rune(vText))-1:])] Java: ___ [can use (UTF-16 shorts): vTextNew = "" + vText.charAt(vText.length()-1)] [also: vTextNew = vText.substring(vText.length()-1)] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: ___ [can use (codepoints): vTextNew = [...vText].pop()] [also (UTF-16 shorts): vTextNew = vText.slice(-1)] [also: substring] [also (UTF-16 shorts): vTextNew = vText.charAt(vText.length-1)] [also (UTF-16 shorts): vTextNew = vText[vText.length-1]] Kotlin: takeLast [e.g. (UTF-16 shorts): vTextNew = vText.takeLast(1)] [also (UTF-16 shorts): vTextNew = vText.last().toString()] [also (UTF-16 shorts): vTextNew = vText[vText.length-1].toString()] PHP: ___ [can use (codepoints): $vTextNew = mb_substr($vText, -1)] [also (UTF-8 bytes): $vTextNew = $vText[-1]] [also (UTF-8 bytes): $vTextNew = $vText[strlen($vText)-1]] Python: ___ [can use (codepoints): vTextNew = vText[-1]] [also (codepoints): vTextNew = vText[len(vText)-1]] R: ___ [can use (codepoints): vTextNew = substring(vText, nchar(vText))] [also (codepoints): vTextNew = substr(vText, nchar(vText), nchar(vText))] [note: substr/substring: equivalent, except substring lets you omit the endpoint] Ruby: ___ [can use (codepoints): vTextNew = vText[-1]] [also (codepoints): vTextNew = vText.slice(-1)] [also (codepoints): vTextNew = vText[vText.length-1]] [WARNING: slice(index) versus slice(start, length)] Rust: ___ [can use (codepoints): vTextNew: String = vText.chars().skip(vText.chars().count()-1).collect()] Scala: ___ [can use (UTF-16 shorts): vTextNew = "" + vText.charAt(vText.length-1)] [also: vTextNew = vText.substring(vText.length-1)] [WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] Swift: suffix [e.g. (codepoints): vTextNew = String(vText.last!)] [also (codepoints): vTextNew = String(vText.suffix(1))] UFL: (StrSort) [sort string based on a delimiter char][see also: Array.Sort] AutoHotkey: Sort [WARNING: case-insensitive by default] C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: ___ Scala: ___ Swift: ___ UFL: (StrAlphabetize) [or StrAlphabetise/StrSortChars][alphabetise characters in string (case sensitive)][see also: Array.Sort] AutoHotkey: ___ C++: std::sort [e.g. std::sort(vText.begin(), vText.end())] [WARNING: sorts UTF-8 bytes] C#: ___ Crystal: ___ [can use: vText.chars.sort.join] Excel: ___ Excel VBA: ___ Go: ___ [can use: oArray := strings.Split(vText, ""); sort.Sort(sort.StringSlice(oArray)); vTextNew := strings.Join(oArray, "")] Java: ___ JavaScript: ___ [can use: [...vText].sort().join("")] Kotlin: ___ PHP: ___ Python: ___ R: ___ [can use: paste(sort(unlist(strsplit(vText, "")), method="radix"), collapse="")] [note (case-sensitive): 'radix' sorts by Unicode codepoint] [WARNING (case-insensitive): omit 'method'] [also: case-sensitive sort and omit 'method', can use e.g. Sys.setlocale("LC_COLLATE", "C")] Ruby: ___ [can use: vText.chars.sort.join] Rust: ___ [can use (sort_by): let mut oVec: Vec<char> = vText.chars().collect(); oVec.sort_by(|v1,v2| v1.cmp(v2)); let vTextNew = oVec.into_iter().collect::<String>()] Scala: sorted [e.g. vText = vText.sorted] Swift: ___ UFL: (StrAlphabetizeCasIns) [or StrAlphabetiseCasIns/StrSortCharsCasIns][alphabetise characters in string (case insensitive)][see also: Array.SortCasIns] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ [can use: vText.chars.sort{|v1,v2| v1.downcase <=> v2.downcase}.join] [also: vText.chars.sort{|v1,v2| v1.to_s.compare(v2.to_s, true)}.join] Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ [can use: [...vText].sort((v1,v2)=>v1.localeCompare(v2, undefined, {sensitivity:"accent"})).join("")] Kotlin: ___ PHP: ___ Python: ___ R: ___ [can use: paste(sort(unlist(strsplit(vText, ""))), collapse="")] [WARNING (case-insensitive): omit 'method'] Ruby: ___ [can use: vText.chars.sort(&:casecmp).join] [also: vText.chars.sort{|v1,v2| v1.downcase <=> v2.downcase}.join] Rust: ___ Scala: ___ Swift: ___ UFL: (StrReverse) [reverse characters in string] AutoHotkey: ___ C++: std::reverse [e.g. reverses in-place: std::reverse(vText.begin(), vText.end())] [WARNING: flips UTF-8 bytes in any non-ASCII chars] [requires: #include <algorithm>] C#: ___ [can use: string[] oChars = Regex.Split(vText, "(?<=.)(?=.)(?![\uDC00-\uDFFF])"); Array.Reverse(oChars); var vTextNew = String.Concat(oChars)] [requires (Regex.Split): using System.Text.RegularExpressions] [note: preserves surrogate pairs] [also: char[] oChars = vText.ToCharArray(); Array.Reverse(oChars); var vTextNew = new string(oChars)] [WARNING (ToCharArray, Reverse): flips UTF-16 shorts in any surrogate pairs] Crystal: reverse [e.g. vTextNew = vText.reverse] [note: preserves surrogate pairs] Excel: ___ Excel VBA: StrReverse [e.g. vTextNew = StrReverse(vText)] [WARNING: flips UTF-16 shorts in any surrogate pairs] Go: ___ [can use: oChars := strings.Split(vText, ""); slices.Reverse(oChars); vTextNew := strings.Join(oChars, "")] [note: preserves surrogate pairs] Java: reverse [e.g. vTextNew = new StringBuilder(vText).reverse().toString()] [note: StringBuilder is faster than StringBuffer] [note: preserves surrogate pairs] JavaScript: ___ [can use: vTextNew = [...vText].reverse().join("")] [note: preserves surrogate pairs] [note: 'Strings are iterated by Unicode code points.'] [also (WARNING: flips UTF-16 shorts in any surrogate pairs): vTextNew = vText.split("").reverse().join("")] Kotlin: reversed [e.g. vTextNew = vText.reversed()] [note: preserves surrogate pairs] PHP: ___ [can use: $vTextNew = implode("", array_reverse(mb_str_split($vText)))] [note: preserves surrogate pairs] [also (WARNING: flips UTF-8 bytes in any non-ASCII chars): $vTextNew = strrev($vText)] Python: ___ [can use: vTextNew = vText[::-1]] [note: preserves surrogate pairs] [note: vText[start:end:step]] R: ___ [can use: vTextNew = paste(rev(unlist(strsplit(vText, ""))), collapse="")] [note: preserves surrogate pairs] Ruby: reverse [e.g. vTextNew = vText.reverse] [note: preserves surrogate pairs] Rust: rev [e.g. vTextNew: String = vText.chars().rev().collect()] [note: preserves surrogate pairs] Scala: reverse [e.g. vTextNew = vText.reverse] [also: vTextNew = StringBuilder(vText).reverse.toString] [WARNING (StringBuilder): this does not preserve surrogate pairs (unlike Java)] Swift: reversed [e.g. vTextNew = String(vText.reversed())] [note: preserves surrogate pairs] UFL: (StrShuffle) [shuffle (randomly sort) characters in string] AutoHotkey: ___ C++: std::shuffle [deprecated: std::random_shuffle] C#: ___ Crystal: shuffle [e.g. vText.chars.shuffle.join] Excel: ___ Excel VBA: ___ Go: ___ [can use: oArray := strings.Split(vText, ""); sort.Slice(oArray, func(_, _ int) bool { return rand.IntN(2) == 0 }); vTextNew := strings.Join(oArray, "")] Java: Collections.shuffle [e.g. var oChars = vText.split(""); Collections.shuffle(Arrays.asList(oChars)); var vTextNew = String.join("", oChars)] [requires: import java.util.*] [WARNING: can split surrogate pairs] JavaScript: ___ Kotlin: ___ PHP: ___ [can use: $oArrayTemp = mb_str_split($vText); shuffle($oArrayTemp); $vTextNew = implode("", $oArrayTemp)] [WARNING: str_shuffle shuffles bytes, not codepoints] Python: random.shuffle [also: random.sample] [e.g. "".join(random.sample(vText,len(vText)))] [note: random.sample returns None] R: ___ [can use: paste(sample(unlist(strsplit(vText, ""))), collapse="")] Ruby: shuffle [e.g. vText.chars.shuffle.join] Rust: ___ [can use: let mut oVec = vText.chars().collect::<Vec<_>>(); oVec.shuffle(&mut rand::thread_rng()); let vTextNew: String = oVec.into_iter().collect()] [requires: use rand::seq::SliceRandom] Scala: ___ [can use: vTextNew = scala.util.Random.shuffle(vText.split("")).mkString(""))] Swift: ___ UFL: Trim/LTrim/RTrim [crop chars from start/end/both (specify a custom list of chars)] AutoHotkey: Trim/LTrim/RTrim C++: ___/___/___ [can use: strspn/wcsspn to count leading chars] C#: Trim/TrimStart/TrimEnd Crystal: strip/lstrip/rstrip [also: lchop/rchop/chomp] Excel: ___/___/___ [note: TRIM only handles whitespace] Excel VBA: ___/___/___ [note: Trim/LTrim/RTrim only handle whitespace] Go: strings.Trim/strings.TrimLeft/strings.TrimRight Java: ___/___/___ [note: trim/strip/stripLeading/stripTrailing only handle whitespace] JavaScript: ___/___/___ [note: trim/trimStart/trimEnd only handle whitespace] Kotlin: trim/trimStart/trimEnd PHP: trim/ltrim/rtrim [also (alias of rtrim): chop] Python: str.strip/str.lstrip/str.rstrip [also (remove any common leading whitespace from lines): textwrap.dedent] R: trimws/trimws/trimws [note: the 'whitespace' param uses RegEx] Ruby: ___/___/___ [note: strip/lstrip/rstrip only handle whitespace] [also: chop/chomp/delete_prefix/delete_suffix] Rust: trim_matches/trim_start_matches/trim_end_matches [also (whitespace only): trim/trim_start/trim_end] [deprecated: trim_left/trim_right] Scala: ___/___/___ [note: trim/strip/stripLeading/stripTrailing only handle whitespace] Swift: ___/___/___ [note: trimmingCharacters only handles whitespace] UFL: (TrimCustomDemo) [crop chars from start and end (specify a custom list of chars)] AutoHotkey: Trim("abcdefghi", "abcghi") C++: ___ C#: "abcdefghi".Trim("abcghi".ToCharArray()) Crystal: "abcdefghi".strip("abcghi") Excel: ___ Excel VBA: ___ Go: strings.Trim("abcdefghi", "abcghi") Java: ___ JavaScript: ___ Kotlin: "abcdefghi".trim(*"abcghi".toCharArray()) PHP: trim("abcdefghi", "abcghi") Python: str.strip("abcdefghi", "abcghi") R: trimws("abcdefghi", whitespace="[abcghi]") Ruby: ___ Rust: "abcdefghi".trim_matches(['a','b','c','g','h','i']) Scala: ___ Swift: ___ UFL: StrDiffFirst [find position of first(/nth) difference][get length of longest common prefix][WARNING: languages may use 0-based/1-based string indexes] AutoHotkey: ___ C++: ___ [note: memcmp/strcmp/wcscmp indicates which is greater] C#: ___ [can use: Zip/TakeWhile/Count] Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ [can use: StringUtils.difference] JavaScript: ___ Kotlin: commonPrefixWith PHP: ___ [note: can apply xor to strings e.g. strspn($vText1 ^ $vText2, "\0")] Python: ___ R: ___ [can use: which(oVec1 != oVec2)[1]] [note: use strsplit to turn strings into vectors] Ruby: ___ Rust: ___ Scala: ___ [can use: StringUtils.difference] Swift: commonPrefix UFL: StrDiffLast [find position of last(/nth-to-last) difference][get length of longest common suffix][or StrDiff (find the nth/nth-to-last difference)][WARNING: languages may use 0-based/1-based string indexes][longest common prefix] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: commonSuffixWith PHP: ___ [note: can apply xor to strings e.g. strspn($vText1 ^ $vText2, "\0")] Python: ___ R: ___ [can use: tail(which(oVec1 != oVec2), 1)] [note: use strsplit to turn strings into vectors] Ruby: ___ Rust: ___ Scala: ___ Swift: ___ UFL: Format [or StrFormat][produce text in a similar way to sprintf (using string interpolation): a format string and parameters][the examples below generate '123 abc 456.789'][see also: RoundDP/SymInterpolateDemo/StrPadZero] AutoHotkey: Format [e.g. Format("{} {} {:.3f}", 123, "abc", 456.7891)] C++: std::format [e.g. std::format("{} {} {:.3f}", 123, "abc", 456.7891)] [also: sprintf/vsprintf] [requires (format): #include <format>] [WARNING (on cpp.sh): used '(double)123' to suppress error message re. ambiguous types] C#: String.Format [e.g. String.Format("{0} {1} {2:f3}", 123, "abc", 456.7891)] Crystal: sprintf [e.g. sprintf("%d %s %.3f", 123, "abc", 456.7891)] Excel: ___ Excel VBA: ___ Go: fmt.Sprintf [e.g. fmt.Sprintf("%d %s %.3f", 123, "abc", 456.7891)] Java: String.format [e.g. String.format("%d %s %.3f", 123, "abc", 456.7891)] JavaScript: ___ [note: JavaScript has template strings] [also: Intl.NumberFormat] Kotlin: String.format [e.g. String.format("%d %s %.3f", 123, "abc", 456.7891)] PHP: sprintf [e.g. sprintf("%d %s %.3f", 123, "abc", 456.7891)] Python: str.format [e.g. "{} {} {:.3f}".format(123, "abc", 456.7891)] R: sprintf [e.g. sprintf("%d %s %.3f", 123, "abc", 456.7891)] Ruby: sprintf [e.g. sprintf("%d %s %.3f", 123, "abc", 456.7891)] [also (%): "%.3f" % 456.7891] Rust: format [e.g. format!("{} {} {:.3}", 123, "abc", 456.7891)] Scala: String.format [e.g. String.format("%d %s %.3f", 123, "abc", 456.7891)] [also: f"$vNum%d $vText%s $vFloat%.3f"] [also (beforehand): var vNum = 123; var vText = "abc"; var vFloat = 456.7891] [also: f"${123}%d ${"abc"}%s ${456.7891}%.3f"] Swift: String [note: with format options] [e.g. String(format:vFormat, arguments:oArray)] [e.g. String(format:vFormat, vNum)] [e.g. String(format:"%d %@ %.3f", 123, "abc", 456.7891)] [requires: import Foundation] UFL: (FormatHexDemo) [dec to hex using the format/sprintf function][e.g. 255 to 'ff' (lower case)][see also: DecToHex] AutoHotkey: Format("{:x}", 255) C++: std::format("{:x}", 255) [requires (format): #include <format>] [WARNING (on cpp.sh): didn't work, would use '(double)255' to suppress error message re. ambiguous types, but not working because '{:x}' expects an integer type] C#: String.Format("{0:x}", 255) Crystal: sprintf("%x", 255) Excel: ___ Excel VBA: ___ Go: fmt.Sprintf("%x", 255) Java: String.format("%x", 255) JavaScript: ___ Kotlin: String.format("%x", 255) PHP: sprintf("%x", 255) Python: "{:x}".format(255) R: sprintf("%x", 255) Ruby: sprintf("%x", 255) [also (%): "%x" % 255] Rust: format!("{:x}", 255) Scala: String.format("%x", 255) [also: f"${255}%x"] Swift: String(format:"%x", 255) [requires: import Foundation] UFL: (FormatBinDemo) [dec to bin using the format/sprintf function][e.g. 255 to '11111111'][see also: DecToBin] AutoHotkey: ___ [WARNING: not handled: Format("{:b}", vNum)] C++: std::format("{:b}", 255) [requires (format): #include <format>] [WARNING (on cpp.sh): didn't work, would use '(double)255' to suppress error message re. ambiguous types, but not working because '{:b}' expects an integer type] C#: String.Format("{0:b}", 255) Crystal: sprintf("%b", 255) Excel: ___ Excel VBA: ___ Go: fmt.Sprintf("%b", 255) Java: ___ [WARNING: 'b' for bool, not bin: String.format("%b", vBool)] JavaScript: ___ Kotlin: ___ [WARNING: 'b' for bool, not bin: String.format("%b", vBool)] PHP: sprintf("%b", 255) Python: "{:b}".format(255) R: ___ [WARNING: not handled: sprintf("%b", vNum)] Ruby: sprintf("%b", 255) [also (%): "%b" % 255] Rust: format!("{:b}", 255) Scala: ___ [WARNING: 'b' for bool, not bin: String.format("%b", vBool)] [also: f"${true}%b"] Swift: ___ [WARNING: not handled: String(format:"%x", vNum)] [requires: import Foundation] UFL: StrPadZero [or FormatPad/StrFormatPad][pad integer with leading zeros][the examples below generate '0012'][see also: StrPadLeft/StrPadRight/StrPadBoth] AutoHotkey: Format [e.g. Format("{:04}", 12)] C++: std::format [e.g. std::format("{:04.0f}", 12)] [requires (format): #include <format>] [WARNING (on cpp.sh): used '(double)12' to suppress error message re. ambiguous types] C#: String.Format [e.g. String.Format("{0:d4}", 12)] Crystal: sprintf [e.g. sprintf("%04d", 12)] Excel: ___ Excel VBA: ___ Go: fmt.Sprintf [e.g. fmt.Sprintf("%04d", 12)] Java: String.format [e.g. String.format("%04d", 12)] JavaScript: ___ [note: JavaScript has template strings] Kotlin: String.format [e.g. String.format("%04d", 12)] PHP: sprintf [e.g. sprintf("%04d", 12)] Python: str.format [e.g. "{:04d}".format(12)] [also: str.zfill] R: sprintf [e.g. sprintf("%04d", 12)] Ruby: sprintf [e.g. sprintf("%04d", 12)] [also (%): "%04d" % 12] Rust: format [e.g. format!("{:04}", 12)] Scala: String.format [e.g. String.format("%04d", 12)] Swift: String [note: with format options] [e.g. String(format:"%04d", 12)] [requires: import Foundation] UFL: (StrConcat) [or StrPrepended/StrAppended][creates a new string][see also: StrJoin/Array.Join/Format/StrPrepend/StrAppend/OpConcat] AutoHotkey: ___ [can use: .] [can use: auto-concat] C++: ___ [can use: +] [also: strcat/wcscat] C#: Concat [e.g. vTextNew = String.Concat(vText1, vText2, vText3)] [can use: +] Crystal: ___ [can use: +] Excel: CONCAT [can use: &] [e.g. =A1&A2] [deprecated: CONCATENATE] [e.g. CONCATENATE(A1,A2,A3)] Excel VBA: ___ [also: &] [also: +] Go: ___ [can use: +] Java: concat [e.g. vTextNew = vText1.concat(vText2)] [can use: +] [also: String.join("", vText1, vText2, vText3)] JavaScript: concat [e.g. vTextNew = vText1.concat(vText2)] [can use: +] Kotlin: plus [e.g. vTextNew = vText1.plus(vText2)] [can use: +] [deprecated: concat] PHP: ___ [can use: .] Python: operator.concat [e.g. vTextNew = operator.concat(vText1, vText2)] [can use: +] [can use: "".join([vText1, vText2, vText3])] R: ___ [can use: paste0(vText1, vText2, vText3)] [also: paste(vText1, vText2, vText3, sep="")] Ruby: ___ [can use: +] [WARNING: concat() modifies the string] Rust: ___ [can use: format!("{}{}", vText1, vText2)] [also: vText1 + &vText2] [also: vText1.to_owned() + vText2] [also: vText1.clone() + &vText2] [WARNING: concat!() only accepts string literals, not variables] Scala: concat [e.g. vTextNew = vText1.concat(vText2)] [can use: +] [also: String.join("", vText1, vText2, vText3)] Swift: ___ [can use: +] UFL: StrPadLeft [e.g. pad 'abc' with 3 chars (padding on the left)][WARNING: pad left = justify right][see also: StrRept/StrPadZero] AutoHotkey: ___ [e.g. spaces: Format("{: 6}", "abc")] [e.g. zeros: Format("{:06}", "abc")] C++: std::format [e.g. std::format("{:_>6s}", "abc")] [also: sprintf/vsprintf] C#: PadLeft [e.g. "abc".PadLeft(6, '_')] Crystal: rjust [e.g. "abc".rjust(6, '_')] Excel: ___ [e.g. zeros: TEXT(123,"000000")] [e.g. zeros: TEXT(123,REPT("0",6))] [note: fails on non-numbers] Excel VBA: ___ [e.g. zeros: WorksheetFunction.Text(123, "000000")] [e.g. zeros: WorksheetFunction.Text(123, WorksheetFunction.Rept("0", 6))] [note: fails on non-numbers] Go: ___ [e.g. spaces: fmt.Sprintf("%6s", "abc")] Java: ___ [e.g. String.format("%1$6s", "abc")] JavaScript: padStart [e.g. "abc".padStart(6, "_")] Kotlin: padStart [e.g. "abc".padStart(6, '_')] PHP: mb_str_pad [e.g. mb_str_pad("abc", 6, "_", STR_PAD_LEFT)] [also (bytes): str_pad] Python: str.rjust [e.g. "abc".rjust(6, "_")] [note: str.zfill pads leading zeros, e.g. "abc".zfill(6)] R: ___ [e.g. spaces: format("abc", justify="l", width=6)] Ruby: rjust [e.g. "abc".rjust(6, "_")] Rust: format [e.g. format!("{:_>6}", "abc")] Scala: ___ [e.g. String.format("%1$6s", "abc")] Swift: ___ [e.g. String(String("abc".reversed()).padding(toLength:6, withPad:"_", startingAt:0).reversed())] [note: padding only pads left, reverse text twice as a workaround] [also: stringByPaddingToLength] [requires (padding): import Foundation] UFL: StrPadRight [e.g. pad 'abc' with 3 chars (padding on the right)][WARNING: pad right = justify left][see also: StrRept] AutoHotkey: ___ [e.g. spaces: Format("{:-06}", "abc")] C++: std::format [e.g. std::format("{:_<6s}", "abc")] C#: PadRight [e.g. "abc".PadRight(6, '_')] Crystal: ljust [e.g. "abc".ljust(6, '_')] Excel: ___ Excel VBA: ___ Go: ___ [e.g. spaces: fmt.Sprintf("%-6s", "abc")] Java: ___ [e.g. String.format("%1$-6s", "abc")] JavaScript: padEnd [e.g. "abc".padEnd(6, "_")] Kotlin: padEnd [e.g. "abc".padEnd(6, '_')] PHP: mb_str_pad [e.g. mb_str_pad("abc", 6, "_", STR_PAD_RIGHT)] [note: STR_PAD_RIGHT can be omitted, but adds clarity] [also (bytes): str_pad] Python: str.ljust [e.g. "abc".ljust(6, "_")] R: ___ [e.g. spaces: format("abc", justify="r", width=6)] [note: justify="r" can be omitted, but adds clarity] Ruby: ljust [e.g. "abc".ljust(6, "_")] Rust: format [e.g. format!("{:_<6}", "abc")] Scala: ___ [e.g. String.format("%1$-6s", "abc")] Swift: padding [e.g. e.g. "abc".padding(toLength:6, withPad:"_", startingAt:0)] [also: stringByPaddingToLength] [requires (padding): import Foundation] UFL: (StrPadBoth) [or StrPadBothSides][e.g. pad 'abc' with 3 chars either side][justify centre, align centre][see also: StrRept] AutoHotkey: ___ C++: std::format [e.g. std::format("{:_^9s}", "abc")] C#: ___ Crystal: center [e.g. "abc".center(9, '_')] Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: mb_str_pad [e.g. mb_str_pad("abc", 9, "_", STR_PAD_BOTH)] [also (bytes): str_pad] Python: format [e.g. "{:_^9}".format("abc")] R: ___ [e.g. spaces: format("abc", justify="c", width=9)] Ruby: center [e.g. "abc".center(9, "_")] Rust: format [e.g. format!("{:_^9}", "abc")] Scala: ___ Swift: ___ UFL: StrSpan/StrCompSpan [span / complementary span][e.g. span: count the leading whitespace chars][e.g. span: count how many chars would be removed by a left trim][complementary span: count leading chars not in list][see also: RegExMatchIndex/LTrim] AutoHotkey: ___/___ C++: strspn/strcspn [also: wcsspn/wcscspn] [note: 'Returns the length of the maximum initial segment (span) of [dest], that consists of only the characters [found (strspn)/not found (strcspn)] in [src].'] C#: ___/___ Crystal: ___/___ [can use: scan] Excel: ___/___ Excel VBA: ___/___ Go: ___/___ Java: ___/___ JavaScript: ___/___ Kotlin: ___/___ PHP: strspn/strcspn Python: ___/___ R: ___/___ Ruby: ___/___ [can use: scan] Rust: ___/___ Scala: ___/___ Swift: ___/___ UFL: (CharIsDigitCountDemo) [count the number of chars considered digits][e.g. in the examples below, all reported count 10] AutoHotkey: ___ [can use: IsDigit(Chr(vOrd))] C++: ___ [can use: isdigit(vChar)] C#: Console.WriteLine(String.Join(",", Enumerable.Range(0, 127).Count(v=>Char.IsAsciiDigit((char)v)))) [requires: using System.Linq] [also: Char.IsDigit] Crystal: p (0..127).count{|v| v.chr.ascii_number?} Excel: ___ Excel VBA: ___ Go: ___ [can use: fmt.Println(vCount)] [beforehand: vCount := 0; for i := 0; i <= 127; i++ {if unicode.IsDigit(rune(i)) {vCount++}}] Java: System.out.println(IntStream.rangeClosed(0, 127).filter(v->Character.isDigit(v)).count()) [requires: import java.util.stream.*] JavaScript: ___ Kotlin: println((0..127).count{Character.isDigit(it)}) PHP: var_dump(count(array_values(array_filter(range(0, 127), fn($v)=>ctype_digit(mb_chr($v)))))) Python: print(len(list(filter(lambda v:chr(v).isdigit(), range(0, 127+1))))) [also: print(sum(1 for v in range(0, 127+1) if chr(v).isdigit()))] R: ___ Ruby: ___ Rust: println!("{:?}", (0..=127).filter(|v| char::from_u32(*v as u32).unwrap().is_ascii_digit()).count()) Scala: println(Range.inclusive(0, 127).count(Character.isDigit(_))) Swift: print((0...127).filter{Character(UnicodeScalar($0)!).isNumber}.count) UFL: (CharIsAlphaCountDemo) [count the number of chars considered letters][e.g. in the examples below, all reported count 52 (i.e. 26*2)] AutoHotkey: ___ [can use: IsAlpha(Chr(vOrd))] C++: ___ [can use: isalpha(vChar)] C#: Console.WriteLine(String.Join(",", Enumerable.Range(0, 127).Count(v=>Char.IsAsciiLetter((char)v)))) [requires: using System.Linq] [also: Char.IsLetter] Crystal: p (0..127).count{|v| v.chr.ascii_letter?} Excel: ___ Excel VBA: ___ Go: ___ [can use: fmt.Println(vCount)] [beforehand: vCount := 0; for i := 0; i <= 127; i++ {if unicode.IsLetter(rune(i)) {vCount++}}] Java: System.out.println(IntStream.rangeClosed(0, 127).filter(v->Character.isLetter(v)).count()) [requires: import java.util.stream.*] JavaScript: ___ Kotlin: println((0..127).count{Character.isLetter(it)}) PHP: var_dump(count(array_values(array_filter(range(0, 127), fn($v)=>ctype_alpha(mb_chr($v)))))) Python: print(len(list(filter(lambda v:chr(v).isalpha(), range(0, 127+1))))) R: ___ Ruby: ___ Rust: println!("{:?}", (0..=127).filter(|v| char::from_u32(*v as u32).unwrap().is_ascii_alphabetic()).count()) Scala: println(Range.inclusive(0, 127).count(Character.isLetter(_))) Swift: print((0...127).filter{Character(UnicodeScalar($0)!).isLetter}.count) UFL: (StrIsAlnumRegExDemo) [string contains ASCII letter chars (A-Z/a-z) and/or digits (0-9) only, string can be blank, check via RegEx][WARNING: some allow non-ASCII letters][see also: RegExMatchBool] AutoHotkey: vIsAlnum := RegExMatch(vText, "^[A-Za-z0-9]*$") C++: vIsAlnum = std::regex_search(vText, oMatch, oRegEx) [beforehand: std::smatch oMatch] [std::regex oRegEx("^[A-Za-z0-9]*$")] [requires: #include <regex>] C#: vIsAlnum = Regex.Match(vText, "^[A-Za-z0-9]*$").Success [requires: using System.Text.RegularExpressions] Crystal: vIsAlnum = Regex.new("^[A-Za-z0-9]*$").matches?(vText) [also: vIsAlnum = (vText.index(Regex.new("^[A-Za-z0-9]*$")) != nil)] [also: vIsAlnum = ((vText =~ Regex.new("^[A-Za-z0-9]*$")) != nil)] Excel: ___ Excel VBA: ___ Go: vIsAlnum := oRegEx.MatchString(vText) [beforehand: oRegEx, vErr := regexp.Compile("^[A-Za-z0-9]*$")] Java: vIsAlnum = Pattern.compile("^[A-Za-z0-9]*$").matcher(vText).find() [requires: import java.util.regex.Pattern] JavaScript: vIsAlnum = /^[A-Za-z0-9]*$/.test(vText) Kotlin: vIsAlnum = Regex("^[A-Za-z0-9]*$").containsMatchIn(vText) [also: vIsAlnum = (Regex("^[A-Za-z0-9]*$").find(vText) != null)] PHP: $vIsAlnum = !!preg_match("/^[A-Za-z0-9]*$/", $vText) Python: vIsAlnum = (re.compile("^[A-Za-z0-9]*$").search(vText) != None) [requires: import re] R: vIsAlnum = (regexpr("^[A-Za-z0-9]*$", vText)[1] == 1) Ruby: vIsAlnum = Regexp.new("^[A-Za-z0-9]*$").match?(vText) [also: vIsAlnum = (vText.index(Regexp.new("^[A-Za-z0-9]*$")) != nil)] [also: vIsAlnum = ((vText =~ Regexp.new("^[A-Za-z0-9]*$")) != nil)] Rust: vIsAlnum = Regex::new("^[A-Za-z0-9]*$").unwrap().is_match(vText) [also: vIsAlnum = Regex::new("^[A-Za-z0-9]*$").unwrap().find(vText).is_some()] [requires: use regex::Regex] Scala: vIsAlnum = "^[A-Za-z0-9]*$".r.findFirstIn(vText).isDefined Swift: vIsAlnum = (oMatch != nil) [beforehand: oMatch = try Regex("^[A-Za-z0-9]*$").firstMatch(in:vText)] UFL: StrIsDigit [string contains ASCII digit chars (0-9) only, string can be blank][WARNING: some allow non-ASCII digits][see also: RegExMatchBool] AutoHotkey: IsDigit [e.g. vIsDigit := IsDigit(vText)] [also (0-9A-Fa-f, and '0x'/'0X' prefix tolerated if present): IsXDigit(vText)] C++: ___ [can use: vIsDigit = std::regex_search(vText, oMatch, oRegEx)] [beforehand: std::smatch oMatch] [std::regex oRegEx("^\\d*$")] [requires: #include <regex>] C#: ___ [can use: vIsDigit = vText.All(v=>Char.IsAsciiDigit(v))] [requires (All): using System.Linq] [also: Char.IsDigit] Crystal: ___ [can use: vIsDigit = vText.chars.all?{|v|v.ascii_number?}] [also: vText.codepoints.all?{|v|(48..57)===v}] Excel: ___ [can use: ISNUMBER(VALUE(A1))] [WARNING: works correctly for 1-char strings, but for longer strings accepts '-'/'.' etc also] Excel VBA: ___ [can use (for first char of string): vIsDigit = (vText Like "#*")] [WARNING: '*' in Excel VBA is equivalent to '.*' in RegEx] Go: ___ [can use: vIsDigit := oRegEx.MatchString(vText)] [beforehand: oRegEx, vErr := regexp.Compile("^\\d*$")] Java: ___ [can use: vIsDigit = vText.chars().allMatch(v->Character.isDigit(v))] JavaScript: ___ [can use: vIsDigit = /^\d*$/.test(vText)] Kotlin: ___ [can use: vIsDigit = vText.toCharArray().all{v->v.isDigit() && v.code<128}] PHP: ctype_digit [e.g. $vIsDigit = ctype_digit($vText)] [WARNING: a blank string returns false] Python: isdigit [e.g. vIsDigit = vText.isdigit()] [WARNING: a blank string returns false] R: ___ [can use: vIsDigit = (regexpr("^\\d*$", vText)[1] == 1)] Ruby: ___ [can use: vIsDigit = vText.codepoints.all?{|v|(48..57)===v}] Rust: ___ [can use: vIsDigit = vText.chars().all(|v|v.is_ascii_digit())] Scala: ___ [can use: vIsDigit = vText.forall(Character.isDigit)] [also (alternate syntax): vText forall Character.isDigit] Swift: ___ [can use: vIsDigit = vText.allSatisfy{$0.isNumber}] UFL: CharIsDigit [char is an ASCII digit (0-9)][WARNING: some allow non-ASCII digits] AutoHotkey: IsDigit [e.g. (for strings): vIsDigit := IsDigit(vText)] C++: isdigit [e.g. vIsDigit = isdigit(vChar)] C#: Char.IsAsciiDigit [e.g. vIsDigit = Char.IsAsciiDigit(vChar)] [also: Char.IsDigit] Crystal: ascii_number [e.g. vIsDigit = vChar.ascii_number?] Excel: ___ [can use (for strings): ISNUMBER(VALUE(A1))] [WARNING: works consistently with 1-char strings, but for longer strings accepts '-'/'.' etc also] Excel VBA: ___ [can use (for one-char string): vIsDigit = (vText Like "#")] Go: ___ [can use (for ints): vIsDigit := unicode.IsDigit(vOrd)] Java: Character.isDigit [e.g. vIsDigit = Character.isDigit(vChar)] JavaScript: ___ [can use (for strings): vIsDigit = /^\d*$/.test(vText)] Kotlin: Character.isDigit [e.g. vIsDigit = Character.isDigit(vChar)] PHP: ctype_digit [e.g. (for strings): $vIsDigit = ctype_digit($vText)] [WARNING: a blank string returns false] Python: isdigit [e.g. (for strings): vIsDigit = vText.isdigit()] [WARNING: a blank string returns false] R: ___ [can use (for one-char string): vIsDigit = (regexpr("^\\d$", vText)[1] == 1)] Ruby: ___ [can use (for strings): vIsDigit = ((48..57) === vText[vPos].ord)] Rust: is_ascii_digit [e.g. vIsDigit = vChar.is_ascii_digit()] [WARNING: is_digit allows digits *and letters*] Scala: Character.isDigit [e.g. vIsDigit = Character.isDigit(vChar)] Swift: isNumber [e.g. vIsDigit = vChar.isNumber] UFL: StrIsAlpha [string contains ASCII letter chars (A-Z/a-z) only, string can be blank][WARNING: some allow non-ASCII letters][see also: RegExMatchBool] AutoHotkey: IsAlpha [e.g. vIsAlpha := IsAlpha(vText)] C++: ___ [can use: vIsAlpha = std::regex_search(vText, oMatch, oRegEx)] [beforehand: std::smatch oMatch] [std::regex oRegEx("^[A-Za-z]*$")] [requires: #include <regex>] C#: ___ [can use: vIsAlpha = vText.All(v=>Char.IsAsciiLetter(v))] [requires (All): using System.Linq] [also: Char.IsLetter] Crystal: ___ [can use: vIsAlpha = vText.chars.all?{|v|v.ascii_letter?}] [also: vText.codepoints.all?{|v|(97..122)===v || (65..90)===v}] Excel: ___ [can use (for first char of string): AND(CODE(LOWER(A1))>=97,CODE(LOWER(A1))<=122)] Excel VBA: ___ [can use (for first char of string): vIsAlpha = (vText Like "[A-Za-z]*")] [WARNING: '*' in Excel VBA is equivalent to '.*' in RegEx] Go: ___ [can use: vIsAlpha := oRegEx.MatchString(vText)] [beforehand: oRegEx, vErr := regexp.Compile("^[A-Za-z]*$")] Java: ___ [can use: vIsAlpha = vText.chars().allMatch(v->Character.isLetter(v))] JavaScript: ___ [can use: vIsAlpha = /^[A-Za-z]*$/.test(vText)] Kotlin: ___ [can use: vIsAlpha = vText.toCharArray().all{v->v.isLetter() && v.code<128}] PHP: ctype_alpha [e.g. $vIsAlpha = ctype_alpha($vText)] [WARNING: a blank string returns false] Python: isalpha [e.g. vIsAlpha = vText.isalpha()] [WARNING: a blank string returns false] R: ___ [can use: vIsAlpha = (regexpr("^[A-Za-z]*$", vText)[1] == 1)] Ruby: ___ [can use: vIsAlpha = vText.codepoints.all?{|v|(97..122)===v || (65..90)===v}] Rust: ___ [can use: vIsAlpha = vText.chars().all(|v|v.is_ascii_alphabetic())] Scala: ___ [can use: vIsAlpha = vText.forall(Character.isLetter)] [also (alternate syntax): vText forall Character.isLetter] Swift: ___ [can use: vIsAlpha = vText.allSatisfy{$0.isLetter}] UFL: CharIsAlpha [char is an ASCII letter (A-Z/a-z)][WARNING: some allow non-ASCII letters] AutoHotkey: IsAlpha [e.g. (for strings): vIsAlpha := IsAlpha(vText)] C++: isalpha [e.g. vIsAlpha = isalpha(vChar)] C#: Char.IsAsciiLetter [e.g. vIsAlpha = Char.IsAsciiLetter(vChar)] [also: Char.IsLetter] Crystal: ascii_letter [e.g. vIsAlpha = vChar.ascii_letter?] Excel: ___ [can use (for first char of string): AND(CODE(LOWER(A1))>=97,CODE(LOWER(A1))<=122)] Excel VBA: ___ [can use (for one-char string): vIsAlpha = (vText Like "[A-Za-z]")] Go: ___ [can use (for ints): vIsAlpha := unicode.IsLetter(vOrd)] Java: Character.isLetter [e.g. vIsAlpha = Character.isLetter(vChar)] JavaScript: ___ [can use (for strings): vIsAlpha = /^[A-Za-z]*$/.test(vText)] Kotlin: Character.isLetter [e.g. vIsAlpha = Character.isLetter(vChar)] PHP: ctype_alpha [e.g. (for strings): $vIsAlpha = ctype_alpha($vText)] [WARNING: a blank string returns false] Python: isalpha [e.g. (for strings): vIsAlpha = vText.isalpha()] [WARNING: a blank string returns false] R: ___ [can use (for one-char string): vIsAlpha = (regexpr("^[A-Za-z]$", vText)[1] == 1)] Ruby: ___ [can use (for strings): vIsAlpha = ((97..122) === vText[vPos].ord || (65..90) === vText[vPos].ord)] Rust: is_ascii_alphabetic [e.g. vIsAlpha = vChar.is_ascii_alphabetic()] Scala: Character.isLetter [e.g. vIsAlpha = Character.isLetter(vChar)] Swift: isLetter [e.g. vIsAlpha = vChar.isLetter] UFL: (StrIsUpper) [string contains upper-case ASCII letter chars (A-Z) only, string can be blank][WARNING: some allow non-ASCII letters][note: this differs from: vText == StrUpper(vText)][see also: RegExMatchBool] AutoHotkey: IsUpper [e.g. vIsUpper := IsUpper(vText)] C++: ___ [can use: vIsUpper = std::regex_search(vText, oMatch, oRegEx)] [beforehand: std::smatch oMatch] [std::regex oRegEx("^[A-Z]*$")] [requires: #include <regex>] C#: ___ [can use: vIsUpper = vText.All(v=>Char.IsAsciiLetterUpper(v))] [requires (All): using System.Linq] [also: Char.IsUpper] Crystal: ___ [can use: vIsUpper = vText.chars.all?{|v|v.ascii_uppercase?}] [also: vText.codepoints.all?{|v|(65..90)===v}] Excel: ___ [can use (for first char of string): AND(CODE(A1)>=65,CODE(A1)<=90)] Excel VBA: ___ [can use (for first char of string): vIsUpper = (vText Like "[A-Z]*")] [WARNING: '*' in Excel VBA is equivalent to '.*' in RegEx] [WARNING: case-insensitive if use 'Option Compare Text'] Go: ___ [can use: vIsUpper := oRegEx.MatchString(vText)] [beforehand: oRegEx, vErr := regexp.Compile("^[A-Z]*$")] Java: ___ [can use: vIsUpper = vText.chars().allMatch(v->Character.isUpperCase(v))] JavaScript: ___ [can use: vIsUpper = /^[A-Z]*$/.test(vText)] Kotlin: ___ [can use: vIsUpper = vText.toCharArray().all{v->v.isUpperCase() && v.code<128}] PHP: ctype_upper [e.g. $vIsUpper = ctype_upper($vText)] [WARNING: a blank string returns false] Python: ___ [can use: vIsUpper = (vText.isalpha() and vText.isupper())] [WARNING (isalpha/isupper): a blank string returns false] [also: vIsUpper = (re.fullmatch("^[A-Z]*$", vText) != None)] [WARNING: isupper: 'True if all cased characters in the string are uppercase and there is at least one cased character'] R: ___ [can use: vIsUpper = (regexpr("^[A-Z]*$", vText)[1] == 1)] Ruby: ___ [can use: vIsUpper = vText.codepoints.all?{|v|(65..90)===v}] Rust: ___ [can use: vIsUpper = vText.chars().all(|v|v.is_ascii_uppercase())] Scala: ___ [can use: vIsUpper = vText.forall(Character.isUpperCase)] [also (alternate syntax): vText forall Character.isUpperCase] Swift: ___ [can use: vIsUpper = vText.allSatisfy{$0.isUppercase}] UFL: (CharIsUpper) [char is an upper-case ASCII letter (A-Z)][WARNING: some allow non-ASCII letters] AutoHotkey: IsUpper [e.g. (for strings): vIsUpper := IsUpper(vText)] C++: isupper [e.g. vIsUpper = isupper(vChar)] C#: Char.IsAsciiLetterUpper [e.g. vIsUpper = Char.IsAsciiLetterUpper(vChar)] [also: Char.IsUpper] Crystal: ascii_uppercase [e.g. vIsUpper = vChar.ascii_uppercase?] [also (for strings): vIsUpper = ((65..90) === vText[vPos].ord)] Excel: ___ [can use (for first char of string): AND(CODE(A1)>=65,CODE(A1)<=90)] Excel VBA: ___ [can use (for one-char string): vIsUpper = (vText Like "[A-Z]")] [WARNING: case-insensitive if use 'Option Compare Text'] Go: unicode.IsUpper [can use (for ints): vIsUpper := unicode.IsUpper(vOrd)] Java: Character.isUpperCase [e.g. vIsUpper = Character.isUpperCase(vChar)] JavaScript: ___ [can use (for strings): vIsUpper = /^[A-Z]*$/.test(vText)] Kotlin: Character.isUpperCase [e.g. vIsUpper = Character.isUpperCase(vChar)] PHP: ctype_upper [e.g. (for strings): $vIsUpper = ctype_upper($vText)] [WARNING: a blank string returns false] Python: ___ [can use (for strings): vIsUpper = (vText.isalpha() and vText.isupper())] [WARNING (isalpha/isupper): a blank string returns false] [also: vIsUpper = (re.fullmatch("^[A-Z]*$", vText) != None)] [WARNING: isupper: 'True if all cased characters in the string are uppercase and there is at least one cased character'] R: ___ [can use (for one-char string): vIsUpper = (regexpr("^[A-Z]$", vText)[1] == 1)] Ruby: ___ [can use (for strings): vIsUpper = ((65..90) === vText[vPos].ord)] Rust: is_ascii_uppercase [e.g. vIsUpper = vChar.is_ascii_uppercase()] Scala: Character.isUpperCase [e.g. vIsUpper = Character.isUpperCase(vChar)] Swift: isUppercase [e.g. vIsUpper = vChar.isUppercase] UFL: (StrIsLower) [string contains lower-case ASCII letter chars (a-z) only, string can be blank][WARNING: some allow non-ASCII letters][note: this differs from: vText == StrLower(vText)][see also: RegExMatchBool] AutoHotkey: IsLower [e.g. vIsLower := IsLower(vText)] C++: ___ [can use: vIsLower = std::regex_search(vText, oMatch, oRegEx)] [beforehand: std::smatch oMatch] [std::regex oRegEx("^[a-z]*$")] [requires: #include <regex>] C#: ___ [can use: vIsLower = vText.All(v=>Char.IsAsciiLetterLower(v))] [requires (All): using System.Linq] [also: Char.IsLower] Crystal: ___ [can use: vIsLower = vText.chars.all?{|v|v.ascii_lowercase?}] [also: vText.codepoints.all?{|v|(97..122)===v}] Excel: ___ [can use (for first char of string): AND(CODE(A1)>=97,CODE(A1)<=122)] Excel VBA: ___ [can use (for first char of string): vIsLower = (vText Like "[a-z]*")] [WARNING: '*' in Excel VBA is equivalent to '.*' in RegEx] [WARNING: case-insensitive if use 'Option Compare Text'] Go: ___ [can use: vIsLower := oRegEx.MatchString(vText)] [beforehand: oRegEx, vErr := regexp.Compile("^[a-z]*$")] Java: ___ [can use: vIsLower = vText.chars().allMatch(v->Character.isLowerCase(v))] JavaScript: ___ [can use: vIsLower = /^[a-z]*$/.test(vText)] Kotlin: ___ [can use: vIsLower = vText.toCharArray().all{v->v.isLowerCase() && v.code<128}] PHP: ctype_lower [e.g. $vIsLower = ctype_lower($vText)] [WARNING: a blank string returns false] Python: ___ [can use: vIsLower = (vText.isalpha() and vText.islower())] [WARNING (isalpha/islower): a blank string returns false] [also: vIsLower = (re.fullmatch("^[a-z]*$", vText) != None)] [WARNING: islower: 'True if all cased characters in the string are lowercase and there is at least one cased character'] R: ___ [can use: vIsLower = (regexpr("^[a-z]*$", vText)[1] == 1)] Ruby: ___ [can use: vIsLower = vText.codepoints.all?{|v|(97..122)===v}] Rust: ___ [can use: vIsLower = vText.chars().all(|v|v.is_ascii_lowercase())] Scala: ___ [can use: vIsLower = vText.forall(Character.isLowerCase)] [also (alternate syntax): vText forall Character.isLowerCase] Swift: ___ [can use: vIsLower = vText.allSatisfy{$0.isLowercase}] UFL: (CharIsLower) [char is a lower-case ASCII letter (a-z)][WARNING: some allow non-ASCII letters] AutoHotkey: IsLower [e.g. (for strings): vIsLower := IsLower(vText)] C++: islower [e.g. vIsLower = islower(vChar)] C#: Char.IsAsciiLetterLower [e.g. vIsLower = Char.IsAsciiLetterLower(vChar)] [also: Char.IsLower] Crystal: ascii_lowercase [e.g. vIsLower = vChar.ascii_lowercase?] [also (for strings): vIsLower = ((97..122) === vText[vPos].ord)] Excel: ___ [can use (for first char of string): AND(CODE(A1)>=97,CODE(A1)<=122)] Excel VBA: ___ [can use (for one-char string): vIsLower = (vText Like "[a-z]")] [WARNING: case-insensitive if use 'Option Compare Text'] Go: unicode.IsLower [can use (for ints): vIsLower := unicode.IsLower(vOrd)] Java: Character.isLowerCase [e.g. vIsLower = Character.isLowerCase(vChar)] JavaScript: ___ [can use (for strings): vIsLower = /^[a-z]*$/.test(vText)] Kotlin: Character.isLowerCase [e.g. vIsLower = Character.isLowerCase(vChar)] PHP: ctype_lower [e.g. (for strings): $vIsLower = ctype_lower($vText)] [WARNING: a blank string returns false] Python: ___ [can use (for strings): vIsLower = (vText.isalpha() and vText.islower())] [WARNING (isalpha/islower): a blank string returns false] [also: vIsLower = (re.fullmatch("^[a-z]*$", vText) != None)] [WARNING: islower: 'True if all cased characters in the string are lowercase and there is at least one cased character'] R: ___ [can use (for one-char string): vIsLower = (regexpr("^[a-z]$", vText)[1] == 1)] Ruby: ___ [can use (for strings): vIsLower = ((97..122) === vText[vPos].ord)] Rust: is_ascii_lowercase [e.g. vIsLower = vChar.is_ascii_lowercase()] Scala: Character.isLowerCase [e.g. vIsLower = Character.isLowerCase(vChar)] Swift: isLowercase [e.g. vIsLower = vChar.isLowercase] UFL: (StrIsAlnum) [string contains ASCII letter chars (A-Z/a-z) and/or digits (0-9) only, string can be blank][WARNING: some allow non-ASCII letters][see also: RegExMatchBool/StrIsAlnumRegExDemo] AutoHotkey: IsAlnum [e.g. vIsAlnum := IsAlnum(vText)] C++: ___ [can use: vIsAlnum = std::regex_search(vText, oMatch, oRegEx)] [beforehand: std::smatch oMatch] [std::regex oRegEx("^[A-Za-z0-9]*$")] [requires: #include <regex>] C#: ___ [can use: vIsAlnum = vText.All(v=>Char.IsAsciiLetterOrDigit(v))] [requires (All): using System.Linq] [also: Char.IsLetterOrDigit] Crystal: ___ [can use: vIsAlnum = vText.chars.all?{|v|v.ascii_alphanumeric?}] [also: vText.codepoints.all?{|v|(97..122)===v || (65..90)===v || (48..57)===v}] Excel: ___ Excel VBA: ___ [can use (for first char of string): vIsAlnum = (vText Like "[A-Za-z0-9]*")] [WARNING: '*' in Excel VBA is equivalent to '.*' in RegEx] Go: ___ [can use: vIsAlnum := oRegEx.MatchString(vText)] [beforehand: oRegEx, vErr := regexp.Compile("^[A-Za-z0-9]*$")] Java: ___ [can use: vIsAlnum = vText.chars().allMatch(v->Character.isLetterOrDigit(v))] JavaScript: ___ [can use: vIsAlnum = /^[A-Za-z0-9]*$/.test(vText)] Kotlin: ___ [can use: vIsAlnum = vText.toCharArray().all{v->v.isLetterOrDigit() && v.code<128}] PHP: ctype_alnum [e.g. $vIsAlnum = ctype_alnum($vText)] [WARNING: a blank string returns false] Python: isalnum [e.g. vIsAlnum = vText.isalnum()] [WARNING: a blank string returns false] R: ___ [can use: vIsAlnum = (regexpr("^[A-Za-z0-9]*$", vText)[1] == 1)] Ruby: ___ [can use: vIsAlnum = vText.codepoints.all?{|v|(97..122)===v || (65..90)===v || (48..57)===v}] Rust: ___ [can use: vIsAlnum = vText.chars().all(|v|v.is_ascii_alphanumeric())] Scala: ___ [can use: vIsAlnum = vText.forall(Character.isLetterOrDigit)] [also (alternate syntax): vText forall Character.isLetterOrDigit] Swift: ___ [can use: vIsAlnum = vText.allSatisfy{CharacterSet.alphanumerics.contains($0.unicodeScalars.first!)}] [requires: import Foundation] UFL: (CharIsAlnum) [char is an ASCII letter (A-Z/a-z) or a digit (0-9)][WARNING: some allow non-ASCII letters] AutoHotkey: IsAlnum [e.g. (for strings): vIsAlnum := IsAlnum(vText)] C++: isalnum [e.g. vIsAlnum = isalnum(vChar)] C#: Char.IsAsciiLetterOrDigit [e.g. vIsAlnum = Char.IsAsciiLetterOrDigit(vChar)] [also: Char.IsLetterOrDigit] Crystal: ascii_alphanumeric [e.g. vIsAlnum = vChar.ascii_alphanumeric?] [also (for strings): vIsAlnum = ((97..122) === vText[vPos].ord || (65..90) === vText[vPos].ord || (48..57) === vText[vPos].ord)] Excel: ___ Excel VBA: ___ [can use (for one-char string): vIsAlnum = (vText Like "[A-Za-z0-9]")] Go: ___ [can use (for ints): vIsAlnum := (unicode.IsLetter(vOrd) || unicode.IsDigit(vOrd))] Java: Character.isLetterOrDigit [e.g. vIsAlnum = Character.isLetterOrDigit(vChar)] JavaScript: ___ [can use (for strings): vIsAlnum = /^[A-Za-z0-9]*$/.test(vText)] Kotlin: Character.isLetterOrDigit [e.g. vIsAlnum = Character.isLetterOrDigit(vChar)] PHP: ctype_alnum [e.g. (for strings): $vIsAlnum = ctype_alnum($vText)] [WARNING: a blank string returns false] Python: isalnum [e.g. (for strings): vIsAlnum = vText.isalnum()] [WARNING: a blank string returns false] R: ___ [can use (for one-char string): vIsAlnum = (regexpr("^[A-Za-z0-9]$", vText)[1] == 1)] Ruby: ___ [can use (for strings): vIsAlnum = ((97..122) === vText[vPos].ord || (65..90) === vText[vPos].ord || (48..57) === vText[vPos].ord)] Rust: is_ascii_alphanumeric [e.g. vIsAlnum = vChar.is_ascii_alphanumeric()] Scala: Character.isLetterOrDigit [e.g. vIsAlnum = Character.isLetterOrDigit(vChar)] Swift: ___ [can use: vIsAlnum = CharacterSet.alphanumerics.contains(vChar.unicodeScalars.first!)] [requires: import Foundation] UFL: StrIsAscii [string contains ASCII chars (0-127) only, string can be blank][see also: RegExMatchBool] AutoHotkey: ___ [can use: vIsAscii := !RegExMatch(vText, "[^[:ascii:]]")] [can use: DllCall with WideCharToMultiByte and codepage 20127 (us-ascii)] C++: ___ [can use: vIsAscii = std::regex_search(vText, oMatch, oRegEx)] [beforehand: std::smatch oMatch] [std::regex oRegEx("^[\\x00-\\x7F]*$")] [requires: #include <regex>] C#: ___ [can use: vIsAscii = vText.All(v=>Char.IsAscii(v))] [requires (All): using System.Linq] Crystal: ascii_only [e.g. vIsAscii = vText.ascii_only?] Excel: ___ [can use (for first char of string): CODE(A1)<128] Excel VBA: ___ [can use (for first char of string): vIsAscii = (AscW(vText) < 128)] Go: ___ [can use: vIsAscii := oRegEx.MatchString(vText)] [beforehand: oRegEx, vErr := regexp.Compile("^[\x00-\x7F]*$")] [note: both of these work: '\x' (string literal), '\\x' (RegEx formatting)] Java: ___ [can use: vIsAscii = vText.chars().allMatch(v->v<128)] JavaScript: ___ [can use: vIsAscii = /^[\x00-\x7F]*$/.test(vText)] Kotlin: ___ [can use: vIsAscii = vText.toCharArray().all{v->v.code<128}] PHP: ___ [can use: $vIsAscii = !preg_match("/[^\x00-\x7F]/", $vText)] [also: $vIsAscii = mb_check_encoding($vText, "ASCII")] [note: both of these work: '\x' (string literal), '\\x' (RegEx formatting)] Python: isascii [e.g. vIsAscii = vText.isascii()] [note: a blank string returns true (unlike various other 'is' methods, e.g. isdigit/isalpha/isalnum)] R: ___ [can use: vIsAscii = all(utf8ToInt(vText) < 128)] [also: vIsAscii = !is.na(iconv(vText, to="ascii"))] [also: showNonASCII(vText)] [WARNING (showNonASCII/iconv): 'this rendering depends on iconv(to = "ASCII") failing to convert, and macOS 14 no longer does so reliably so for example permille'] Ruby: ascii_only [e.g. vIsAscii = vText.ascii_only?] Rust: is_ascii [e.g. vIsAscii = vText.is_ascii()] Scala: ___ [can use: vIsAscii = vText.chars().allMatch(_<128)] Swift: ___ [can use: vIsAscii = (vText.utf8.count == vText.count)] [note: checks if UTF-8 byte count = codepoint count] [also: vIsAscii = vText.allSatisfy{$0.unicodeScalars.first!.value<128}] UFL: CharIsAscii [char is an ASCII char (0-127)] AutoHotkey: ___ [can use (for strings): vIsAscii := !RegExMatch(vText, "[^[:ascii:]]")] [can use (for strings): DllCall with WideCharToMultiByte and codepage 20127 (us-ascii)] C++: isascii [e.g. vIsAscii = isascii(vChar)] C#: Char.IsAscii [e.g. vIsAscii = Char.IsAscii(vChar)] Crystal: ascii [e.g. vIsAscii = vChar.ascii?] Excel: ___ [can use (for first char of string): CODE(A1)<128] Excel VBA: ___ [can use (for first char of string): vIsAscii = (AscW(vText) < 128)] Go: ___ [can use (for ints): vIsAscii := (vOrd <= unicode.MaxASCII)] Java: ___ [can use: vIsAscii = (vChar < 128)] JavaScript: ___ [can use (for strings): vIsAscii = /^[\x00-\x7F]*$/.test(vText)] Kotlin: ___ [can use: vIsAscii = (vChar.code < 128)] PHP: ___ [can use (for strings): $vIsAscii = !preg_match("/[^\x00-\x7F]/", $vText)] [also (for strings): $vIsAscii = mb_check_encoding($vText, "ASCII")] [note: both of these work: '\x' (string literal), '\\x' (RegEx formatting)] Python: isascii [e.g. (for strings): vIsAscii = vText.isascii()] R: ___ [can use (for one-char string): vIsAscii = (utf8ToInt(vText) < 128)] Ruby: ascii_only [e.g. (for strings): vIsAscii = vText.ascii_only?] Rust: is_ascii [e.g. vIsAscii = vChar.is_ascii()] Scala: ___ [can use: vIsAscii = (vChar < 128)] Swift: isASCII [e.g. vIsAscii = vChar.isASCII] UFL: (StrWrap) [e.g. replace some whitespace chars with line breaks, such that each line has a maximum length n] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: wordwrap Python: textwrap.fill [note: textwrap.wrap returns a list of lines] R: strwrap [e.g. strwrap(vText, width=vCount)] Ruby: ___ Rust: ___ Scala: ___ Swift: ___ UFL: ChrUnused [or CharUnused][ChrUnused(oStrings*), return a char not present in oStrings*, e.g. ChrUnused("abc", "def", "ghi") returns Chr(1)][find chars to use as temporary delimiters, or placeholders when swapping strings] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: ___ Scala: ___ Swift: ___ UFL: (StrToName) [or StrToFilename][webpage title to file name (using the same rules as the web browser)] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: ___ Scala: ___ Swift: ___ UFL: (StrPrepend) [prepend string (modify string)] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: prepend [e.g. vText1.prepend(vText2)] [WARNING: prepend() modifies the string] Rust: ___ Scala: ___ Swift: ___ UFL: (StrInsert) [insert string (modify string)][see also: RegExReplace] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: insert [e.g. vText1.insert(vPos, vText2)] Rust: ___ Scala: ___ Swift: ___ UFL: (StrInserted) [insert string (modify string)][see also: RegExReplace] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: ___ Scala: patch [e.g. vTextNew = vText.patch(vPos, vInfix, 0)] Swift: ___ UFL: (StrAppend) [append string (modify string)] AutoHotkey: ___ [can use: .=] C++: ___ [can use: +=] C#: ___ [can use: +=] Crystal: ___ [can use: +=] Excel: ___ [can use: &] [e.g. =A1&A2] Excel VBA: ___ Go: ___ [can use: +=] Java: ___ [can use: +=] JavaScript: ___ [can use: +=] Kotlin: ___ [can use: +=] PHP: ___ [can use: .=] Python: ___ [can use: +=] R: ___ [can use: vText = paste0(vText, vSfx)] [note: to append to every vector element: oVec = paste0(oVec, vSfx)] Ruby: ___ [can use: +=] [also: <<] [also: concat] [WARNING: concat() modifies the string] Rust: ___ [can use: +=] Scala: ___ [can use: +=] Swift: ___ [can use: +=] [also: append] [WARNING: append() modifies the string] UFL: (StrOverwrite) [overwrite string (modify string)][splice string][see also: StrReplace] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ [can use: substr(vText, vPos1, vPos2) = vAfter] Ruby: ___ [also: setbyte] Rust: ___ Scala: ___ Swift: ___ UFL: (StrOverwritten) [overwrite string (return new string)][splice string][see also: StrReplace] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: REPLACE Excel VBA: WorksheetFunction.Replace Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ [can use: list(), item assignment, join()] [e.g. oList = list("abcdefghi"); oList[3:6] = "DEF"; vTextNew = "".join(oList)] [note: replacement can be any length] R: ___ Ruby: ___ Rust: ___ Scala: patch [e.g. vTextNew = vText.patch(vPos, vInfix, vCountDel)] Swift: ___ UFL: (StrNext) [generate the next string e.g. 'abc' to 'abd', e.g. 'azz' to 'baa'][ideally: specify min/max values for each char via an object][see also: Array.Next] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ [can use: succ] Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ [can use: ++] [e.g. $vText++] [e.g. ++$vText] Python: ___ R: ___ Ruby: ___ [can use: succ] [also (alias of succ): next] [also (multiple strings): upto] Rust: ___ Scala: ___ Swift: ___

The Universal Function Library Project: Details

Notes: Function names, parameter names, parameter order, and functionality recommendations, are approximate suggestions; there may be good arguments for alternatives. Function names in parentheses are regarded as somewhat or considerably lower priority. Many example functions are available at JEE.js, the function library that powers this website. Pos parameters are intended to handle one or both of: integer (StartPos) and array ([StartPos, EndPos]). Where Pos is 1-based or 0-based depending on the programming language. CaseSen parameters are case-sensitive by default, but could accept a case-insensitive locale/standard. One simple case-insensitive standard would only treat A-Z/a-z as case-insensitive. Functions that accept or return a position (string index), could return 0-based or 1-based positions. Such functions are labelled with '[WARNING: languages may use 0-based/1-based string indexes]'. Author's Intro: Functions that I would like to see more widely in particular are: StrCount/StrRept (e.g. they are used in algorithms and for counting lines/URLs) StrEquals/StrContains/StrStarts/StrEnds (safer and clearer than alternatives, more convenient than creating a function every time they're needed, and would enable the easier migration of code between programming languages) And languages to have both of: SubStr (pos/length) and StrSlice (pos1/pos2) UFL notes: StrLower/StrUpper format: StrLower(Text, LocaleOrStandard:=unset) format: StrUpper(Text, LocaleOrStandard:=unset) demo: StrLower("ABC Abc abc") ;abc abc abc demo: StrUpper("ABC Abc abc") ;ABC ABC ABC recommendation: one simple standard would only modify chars A-Z/a-z UFL notes: StrTitle [set all words to title case] format: StrTitle(Text, LocaleOrStandard:=unset, Options:=unset) demo: StrTitle("ABC Abc abc") ;Abc Abc Abc recommendation: set all words to title case, some functions simply capitalise the first character recommendation: introduce one or more ISO 'title case' standards recommendation: make available information to match title case in common programs e.g. MS Word/MS Excel recommendation: options could include: only modify words that are lower case recommendation: options could include: words that should not be modified recommendation: options could include: words that should not be forcibly made lower case UFL notes: StrCompare/StrEquals format: StrCompare(Text1, Text2, CaseSen:=unset) [note: returns positive/0/negative] format: StrEquals(Text1, Text2, CaseSen:=unset) demo: StrCompare("abc", "def") ;-1 demo: StrEquals("abc", "def") ;False recommendation: SAFETY: while !StrCompare would be equivalent to StrEquals, for code clarity and code safety, it is worth having both recommendation: it is always worthwhile to have function versions of common operators (e.g. '==') recommendation: StrEquals(a, b, IgnoreCase) beats (a.lowercase == b.lowercase) recommendation: having StrEquals completes the set of StrEquals/StrContains/StrStarts/StrEnds UFL notes: (StrBetween)/(StrBetweenUntil) [between: inclusive to inclusive, until: inclusive to exclusive] format: StrBetween(Needle, Bound1, Bound2, CaseSen:=unset) format: StrBetweenUntil(Needle, Bound1, Bound2, CaseSen:=unset) demo: StrBetween("abc", "a", "abc") ;True demo: StrBetweenUntil("abc", "a", "abc") ;False demo: StrBetweenUntil("abc", "a", "b") ;True recommendation: SAFETY: for safety, it is better if < > <= >= do not compare strings, but instead throw, thus functions are wanted instead UFL notes: Chr [codepoint to character] format: Chr(Number, Options:=unset) demo: Chr(97) ;a recommendation: the default could be to consider codepoints, with an option to consider subunits e.g. UTF-16 2-byte 'chars' UFL notes: Ord [codepoint at start of string] format: Ord(Text, Options:=unset) demo: Ord("abc") ;97 recommendation: the default could be to consider codepoints, with an option to consider subunits e.g. UTF-16 2-byte 'chars' UFL notes: ChrAt/OrdAt [nth character/codepoint of nth character][WARNING: languages may use 0-based/1-based string indexes] format: ChrAt(Text, Pos, Options:=unset) format: OrdAt(Text, Pos, Options:=unset) demo: ChrAt("abc", 2) ;b (1-based position) demo: OrdAt("abc", 2) ;98 (1-based position) recommendation: SAFETY: 1-based positions are safer and more intuitive (but the language may already be using 0-based positions) UFL notes: StrRept [or StrRepeat] format: StrRept(Text, Count) demo: StrRept("abc_", 3) ;abc_abc_abc_ recommendation: 'Rept' rather than 'Repeat', to keep the name short, it can often be used multiple times in one expression UFL notes: StrCount [WARNING: languages may use 0-based/1-based string indexes] format: StrCount(Text, Needle, CaseSen:=unset, Pos:=unset) demo: StrCount("abcabcabc", "a") ;3 UFL notes: StrLen/(StrLenCodepoints) format: StrLen(Text, Options:=unset) demo: StrLen("abc") ;3 recommendation: the default could be to consider codepoints, with an option to consider subunits e.g. UTF-16 2-byte 'chars' UFL notes: StrReplace [replace string with string (no RegEx), all occurrences, there may be an option to replace the first n occurrences][WARNING: languages may use 0-based/1-based string indexes] format: StrReplace(Text, Before, After:="", CaseSen:=unset, &Count:=unset, Limit:=unset, Pos:=unset) demo: StrReplace("abcabcabc", "b", "_",, &Count) ;a_ca_ca_ca_c (Count is 4) demo: StrReplace("abcabcabcabc", "b", "_",, &Count, 1, 7) ;abcabca_cabc (Count is 1) recommendation: if After is omitted, then replace the needle text (Before) with blank strings recommendation: a ByRef Count parameter could return the number of replacements made (alternatively an Options parameter could return [Output, Count] or just Count) recommendation: a Limit parameter could limit how many replacements are made, with no limit by default UFL notes: StrSplit/StrChunk/(StrHatch) [StrSplit: string to array (split by delimiters), StrChunk (or StrSplitLen): string to array (split into chunks of n chars), StrHatch: add a separator every n chars] format: StrSplit(Text, Delim:="", OmitChars:="", MaxParts:=unset) format: StrChunk(Text, Length, Options:=unset) format: StrHatch(Text, Sep, Length:=1, Options:=unset) demo: StrSplit("abc") ;[a,b,c] demo: StrSplit("a,b,c", ",") ;[a,b,c] demo: StrSplit("a|b|c", "|") ;[a,b,c] demo: StrChunk("abcdef", 2) ;[ab,cd,ef] demo: StrHatch("abcdef", "|", 2) ;ab|cd|ef recommendation: StrSplit: if Delim is blank, split into an array of 1-char strings recommendation: if MaxParts is n, return n-1 normal parts, and one 'rest of' part recommendation: Options: for StrChunk/StrHatch, this could start chunking/hatching from the right author's note: for StrHatch: 'Length' then 'Sep' might be a better fit with StrChunk author's note: I coined 'StrHatch', based on the idea of cross-hatching in drawing, adding lines at fixed intervals (but alternative names are welcome) UFL notes: StrJoin [specify separator string, then one or more strings][e.g. StrJoin(vSep, oValues*)] format: StrJoin(Sep, Values*) demo: StrJoin(",", ["a", "b", "c"]) ;a,b,c demo: StrJoin(["=", ","], ["k1", "v1", "k2", "v2"]) ;k1=v1,k2=v2 UFL notes: StrContains/InStr/InStrRev [WARNING: languages may use 0-based/1-based string indexes] format: StrContains(Text, Needle, CaseSen:=unset) format: InStr(Text, Needle, CaseSen:=unset, Pos:=unset, Occ:=unset) format: InStrRev(Text, Needle, CaseSen:=unset, Pos:=unset, Occ:=unset) recommendation: SAFETY: InStr/InStrRev as separate functions simplifies the usage (search left-to-right versus right-to-left) UFL notes: StrStarts/StrEnds [see also: StrEquals/StrContains] format: StrStarts(Text, Needle, CaseSen:=unset) format: StrEnds(Text, Needle, CaseSen:=unset) UFL notes: RegExMatchIndex [find offset of first match, get text of any substrings][WARNING: languages may use 0-based/1-based string indexes] format: RegExMatchIndex(Text, Needle, &Match:=unset, Pos:=unset) UFL notes: (RegExMatchWhole) format: RegExMatchWhole(Text, Needle, &Match:=unset, Pos:=unset) UFL notes: RegExMatchAll [find all matches][WARNING: languages may use 0-based/1-based string indexes] format: RegExMatchAll(Text, Needle, Pos:=unset) UFL notes: RegExReplace format: RegExReplace(Text, Needle, Replacement:="", &Count:=unset, Limit:=unset, Pos:=unset) UFL notes: StrEscape [or RegExEscape][add escape characters to treat all characters literally rather than as metacharacters] format: StrEscape(Text, CharList:="", Options:=unset) recommendation: CharList to determine which characters to escape recommendation: options could allow RegEx escaping using '\Q' and '\E' UFL notes: SubStr [substring using pos/length][WARNING: languages may use 0-based/1-based string indexes] format: SubStr(Text, Pos, Count) UFL notes: (StrSlice) [substring using pos1/pos2][WARNING: languages may use 0-based/1-based string indexes] format: StrSlice(Text, Pos1, Post2) UFL notes: (StrLeft)/(StrRight) format: StrLeft(Text, Count) format: StrRight(Text, Count) recommendation: SAFETY: unlike other slice functions, these handily avoid using 1-based/0-based positions (string indexes) recommendation: if Text is shorther than Count, return the whole string UFL notes: (StrDropLeft)/(StrDropRight) format: StrDropLeft(Text, Count) format: StrDropRight(Text, Count) recommendation: SAFETY: unlike other slice functions, these handily avoid using 1-based/0-based positions (string indexes) recommendation: if Text is shorther than Count, return a blank string UFL notes: (StrSort) [sort string based on a delimiter char] format: Sort(Text, Options, Callback) format: Sort(Text, Callback) author's note: there are various parameter options, including having a separate Delimiter parameter UFL notes: (StrAlphabetize)/(StrReverse)/(StrShuffle) format: StrAlphabetize(Text, CaseSen:=unset) format: StrReverse(Text) format: StrShuffle(Text) UFL notes: Trim/LTrim/RTrim [crop chars from start/end/both] recommendation: handle any characters, not just whitespace characters format: Trim(Text, OmitChars:=" \t") format: LTrim(Text, OmitChars:=" \t") format: RTrim(Text, OmitChars:=" \t") UFL notes: StrDiff/(StrDiffFirst)/(StrDiffLast) [WARNING: languages may use 0-based/1-based string indexes] format: StrDiff(Text1, Text2, CaseSen:=unset) [note: returns the position of the first difference between 2 strings] UFL notes: Format [produce text in a similar way to sprintf (using string interpolation): a format string and parameters] format: Format(FormatStr, Values*) UFL notes: (StrConcat) format: StrConcat(Values*) UFL notes: StrPadLeft/StrPadRight UFL notes: StrSpan/StrCompSpan [span / complementary span e.g. count the leading whitespace chars] format: JEE_StrSpan(Text, NeedleChars) format: JEE_StrCompSpan(Text, NeedleChars) UFL notes: (StrWrap) UFL notes: ChrUnused [ChrUnused(Strings*), return a char not present in Strings*] format: ChrUnused(Values*) recommendation: an Options object could give more granular control author's note: where possible, consider adding functions that reduce the need for a ChrUnused function (e.g. StrChunk) UFL notes: (StrToName) [or StrToFilename] format: StrToName(Title, LocaleOrStandard) author's note: e.g. for a webpage title, what file name would the web browser save it as

Links (Format/Sprintf):

[AutoHotkey] Format - Syntax & Usage | AutoHotkey v2 [C++] Standard format specification - cppreference.com A `printf` format reference page (cheat sheet) (C, Java, Scala, etc.) | alvinalexander.com [C#] Standard numeric format strings - .NET | Microsoft Learn System.String.Format method - .NET | Microsoft Learn String.Format Method (System) | Microsoft Learn [Crystal] Top Level Namespace - Crystal 1.12.1 [Excel] [Excel VBA] [Go] fmt package - fmt - Go Packages [Java] Formatter (Java Platform SE 8 ) Java String format() method - javatpoint Formatting Numeric Print Output (The Java™ Tutorials > Learning the Java Language > Numbers and Strings) [JavaScript] Template literals (Template strings) - JavaScript | MDN [Kotlin] Formatter (Java Platform SE 8 ) format - Kotlin Programming Language Strings | Kotlin Documentation [PHP] PHP: sprintf - Manual [Python] string — Common string operations — Python 3.12.2 documentation 7.2.2. The string format operator [R] sprintf function - RDocumentation [Ruby] format_specifications - RDoc Documentation [Rust] std::fmt - Rust [Scala] String Interpolation | Scala 3 — Book | Scala Documentation [Swift] String Format Specifiers String Format Specifiers What are the supported Swift String format specifiers? - Stack Overflow

Links (Escape Characters):

E.g. '\t', '\r', '\n'. E.g. '\u' and '\x'. [AutoHotkey] Escape Sequences - Definition & Usage | AutoHotkey v2 [C++] Escape sequences - cppreference.com [C#] Strings - C# Programming Guide - C# | Microsoft Learn [Crystal] String - Crystal [Excel] [Excel VBA] Miscellaneous constants | Microsoft Learn [Go] The Go Programming Language Specification - The Go Programming Language [Java] Characters (The Java™ Tutorials > Learning the Java Language > Numbers and Strings) [JavaScript] Lexical grammar - JavaScript | MDN Character escape: \n, \u{...} - JavaScript | MDN [Kotlin] Characters | Kotlin Documentation [PHP] PHP: Strings - Manual [Python] 2. Lexical analysis — Python 3.12.3 documentation [R] R Language Definition [Ruby] literals - Documentation for Ruby 3.4 [Rust] Tokens - The Rust Reference [Scala] Lexical Syntax | Scala 2.12 [Swift] Strings and Characters | Documentation Character | Apple Developer Documentation