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 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. Note: Scroll to the bottom for 'Format' and escape character (e.g. '\u' and '\x') links. UFL: (StringNewDemo) AutoHotkey: vText := "abc" [type: String] C++: std::string vText = "abc" [type (std::string): NSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE][note: auto vText = "abc" resolves to type 'PKc'] 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: 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: 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"] Swift: var vText = "abc" [type: String] UFL: String [or ToString/AnyToString/ValueToString][anything listed here handles strings/ints/floats/objects, where objects includes 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] C#: ___ [WARNING: no general approaches for primitives/arrays/maps] Crystal: to_s [e.g. vVar.to_s] Excel: ___ Excel VBA: ___ Go: 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: ___ [can use: vVar.toString()][WARNING: toString() only prints type name for arrays][also: oArrayAny.toList().toString()] PHP: var_export [e.g. var_export($vVar, true)] Python: str [e.g. str(vVar)] R: Ruby: to_s [e.g. vVar.to_s] Rust: format [e.g. format!("{:?}", vVar)][e.g. format!("{:#?}", vVar)] 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++: ___ [can use: std::to_string(vNum)] C#: ___ [can use: vNum.ToString()] Crystal: to_s [e.g. vNum.to_s] Excel: TEXT [e.g. TEXT(A1,"General")][e.g. =""&A1] Excel VBA: CStr [e.g. CStr(vNum)] Go: Java: ___ [e.g. String.valueOf(vNum)][e.g. Integer.toString(vNum)][e.g. Double.toString(vNum)][e.g. "" + vNum] JavaScript: String [e.g. String(vNum)] Kotlin: ___ [can use: vNum.toString()] PHP: strval [e.g. strval($vNum)] Python: str [e.g. str(vNum)] R: Ruby: to_s [e.g. vNum.to_s] Rust: ___ [e.g. vNum.to_string()][e.g. format!("{}", 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: 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(oArrayAny)][e.g. vSep.join(oArrayStr)][e.g. vSep.join(map(str, oArrayAny))] R: Ruby: to_s [e.g. oArrayAny.to_s] Rust: format [e.g. format!("{:?}", oArrayAny)][e.g. format!("{:#?}", oArrayAny)] 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] 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: 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)] 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: vText[0]] C#: ___ [can use: vText[0]] Crystal: ___ [can use: vText[0]][also: vText.chars[0]] Excel: ___ Excel VBA: ___ Go: Java: charAt [e.g. vText.charAt(0)] JavaScript: ___ Kotlin: ___ [can use: vText[0]] PHP: ___ Python: ___ R: Ruby: ___ Rust: nth [e.g. vText.chars().nth(0).unwrap()][also (first byte): char::from(vText.as_bytes()[0])] Swift: ___ [can use: Array(vText)[0]] UFL: CharToInt [char type to int type] AutoHotkey: ___ C++: ___ [e.g. (int)vChar] C#: ___ [e.g. (int)vChar] Crystal: ord [e.g. vChar.ord] Excel: ___ Excel VBA: ___ Go: 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] Swift: ___ [e.g. vChar.unicodeScalars.first!.value] UFL: IntToChar [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: 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] Swift: ___ [e.g. Character(UnicodeScalar(vOrd)!)] UFL: StrLower 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: 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: Ruby: downcase [e.g. vText.downcase] Rust: to_lowercase [e.g. vText.to_lowercase()][also: to_ascii_lowercase] Swift: lowercased [e.g. vText.lowercased()] UFL: StrUpper 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: 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: Ruby: upcase [e.g. vText.upcase] Rust: to_uppercase [e.g. vText.to_uppercase()][also: to_ascii_uppercase] Swift: uppercased [e.g. vText.uppercased()] UFL: (StrUpperFirstChar) [capitalise first char, leave other chars unchanged][or StrTitleFirstWordOnly/StrTitleOneWord/StrTitleSentence] AutoHotkey: ___ [can use (UTF-16 shorts): vTextNew := StrUpper(SubStr(vText, 1, 1)) SubStr(vText, 2)][also: vText := 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: 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(0).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[:1].upper() + vText[1:]] R: Ruby: ___ [can use (codepoints): vTextNew = vText.slice(0).upcase + vText.slice(1..)][also: vTextNew = vText[0].upcase + vText[1..]][also (modify a string): vText[0] = vText[0].upcase][WARNING: capitalize makes the 2nd char onwards lower case] Rust: ___ [can use (codepoints): vTextNew = 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] 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: Java: ___ JavaScript: ___ Kotlin: ___ PHP: mb_convert_case [e.g. mb_convert_case($vText, MB_CASE_TITLE)] Python: str.title [e.g. vText.title()] R: Ruby: ___ Rust: ___ Swift: capitalized [e.g. vText.capitalized][requires: import Foundation] UFL: StrCompare [see also: StrEquals] AutoHotkey: StrCompare [WARNING: case-insensitive by default][e.g. StrCompare(vText1, vText2)][note (since AHK v2): < > can't compare strings] C++: compare [e.g. vTextA.compare(vTextB)][also: <=>][can use: < >][also: memcmp/strcmp/strncmp/wcscmp/wcsncmp] C#: String.Compare [e.g. String.Compare(vTextA, vTextB)][note: < > can't compare strings] Crystal: ___ [can use: <=>][e.g. vText1 <=> vText2][can use: < >][also (case-insensitive): vTextA.compare(vTextB, true)] Excel: ___ [can use: < >] Excel VBA: StrComp [e.g. StrComp(vTextA, vTextB)][can use: < >] Go: Java: compareTo [e.g. vTextA.compareTo(vTextB)][also: compareToIgnoreCase][note: < > can't compare strings] JavaScript: ___ [can use: < >] Kotlin: compareTo [e.g. vTextA.compareTo(vTextB)][can use: < >] PHP: substr_compare [WARNING: case-insensitive by default][e.g. substr_compare($vTextA, $vTextB, 0, null, true)][can use: < >] Python: ___ [can use: < >] R: Ruby: ___ [can use: <=>][e.g. vText1 <=> vText2][can use: < >][also (case-insensitive): vTextA.casecmp(vTextB)] Rust: cmp [e.g. vTextA.cmp(vTextB) as i32][can use: < >] Swift: ___ [can use: < >] UFL: StrEquals [see also: StrContains/StrStarts/StrEnds, StrCompare] AutoHotkey: ___ [can use: ==][note: case-insensitive: =] C++: ___ [can use: ==] C#: Equals [can use: ==] Crystal: ___ [can use: ==][also (case-insensitive): vTextA.compare(vTextB, true).zero?] Excel: EXACT [can use: =] Excel VBA: ___ [can use: =] Go: Java: equals [also: equalsIgnoreCase][can use: ==] JavaScript: ___ [can use: ==] Kotlin: equals [can use: ==] PHP: ___ [can use: ==] Python: operator.eq [can use: ==] R: 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] Swift: elementsEqual [can use: ==] UFL: (StrBetween) [inclusive to inclusive] 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: ___ PHP: ___ Python: ___ R: 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] Swift: ___ UFL: (StrBetweenUntil) [inclusive to exclusive] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ [can use: (vMin...vMax) === vText][also: (vMin...vMax).includes?(vText)] Excel: ___ Excel VBA: ___ Go: Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: Ruby: ___ [can use: (vMin...vMax) === vText][also: (vMin...vMax).cover?(vText)][also (if strings same length): (vMin...vMax).include?(vText)] Rust: ___ Swift: ___ UFL: Chr [or 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: Java: ___ [can use (codepoints 0-1114111): new String(new int[]{vOrd}, 0, 1)][also (codepoints 0-65535): Character.toString(vOrd)][also: Character.toChars()][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: 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()] 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)] 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: paste("\x22", "\u221A", "\U{1D11E}", sep="") [note: upper-case 'U': "\U{1D11E}"][also: "\U0001D11E"] Ruby: "\x22" + "\u221A" + "\u{1D11E}" Rust: "".to_string() + "\x22" + "\u{221A}" + "\u{1D11E}" 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: 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: Ruby: ord [e.g. (codepoints 0-1114111): vText.ord] Rust: ___ [can use (codepoints 0-1114111): u32::from(vText.chars().nth(0).unwrap()) as i32] Swift: ___ [can use (codepoints 0-1114111): Int(UnicodeScalar(vText).value)] UFL: ChrAt [nth character (as string) (a substring)][WARNING: languages may use 0-based/1-based string indexes][see also: SubStr][i.e. string to char to string] 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: 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)] 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]] Python: ___ [can use (codepoint): vText[vPos]] R: Ruby: ___ [can use (codepoint): vText[vPos]][also: vText.chars[vPos]] Rust: ___ [can use (codepoint): vText.chars().nth(vPos).unwrap().to_string()] 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: 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: Ruby: ___ [can use: vText[vPos].ord][also: vText.codepoints[vPos]] Rust: ___ [can use: vText.chars().nth(vPos).unwrap() as i32] Swift: ___ 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: 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: Ruby: ___ [can use (* operator): vText * vCount][WARNING: mathematical operator used on strings] Rust: 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] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ [can use: 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: ___ Go: Java: ___ JavaScript: ___ Kotlin: ___ PHP: mb_substr_count [e.g. mb_substr_count($vText, $vNeedle)][also (uses bytes, and has offset/length parameters): substr_count] Python: str.count [e.g. vText.count(vNeedle)] R: Ruby: ___ [can use: vText.scan(vNeedle).count][WARNING: vText.count(vNeedle) counts chars, not substrings] Rust: ___ [can use: vText.matches(vNeedle).count())] 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: length: e.g. 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 [also: 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: 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: Ruby: length [e.g. vText.length][also: vText.size][unit (both): codepoints] Rust: len [e.g. vText.len()][unit: UTF-8 bytes] 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: 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: Ruby: "√".length, "𝄞".length [output: 1,1][unit: codepoints] Rust: "√".len(), "𝄞".len() [output: 3,4][unit: UTF-8 bytes] 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: std::string(vText).length()] C#: ___ [can use: Encoding.UTF8.GetBytes(vText).Length] Crystal: bytesize [e.g. vText.bytesize] Excel: ___ Excel VBA: ___ Go: 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: Ruby: bytesize [e.g. vText.bytesize] Rust: len [e.g. vText.len()] 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 (std::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: 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: 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()] 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, ".",, &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 (std::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: 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: Ruby: length [e.g. vText.length][also: vText.size] Rust: ___ [can use: vText.chars().count()] Swift: ___ [can use: vText.count] UFL: StrGetCapacity [get string capacity][in bytes, unless stated] 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: Java: capacity [e.g. vCapacity = oSB.capacity()] JavaScript: ___ Kotlin: ___ [note: StringBuilder: oSB.capacity()] PHP: ___ Python: ___ R: Ruby: ___ Rust: capacity [e.g. vCapacity = vText.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] 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: 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(vCapacityExtra)][e.g. set total: vText.reserve(vCapacity-vText.len())][also: reserve_exact/shrink_to_fit/shrink_to/truncate] 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] AutoHotkey: StrReplace [WARNING: case-insensitive by default][e.g. vTextNew := StrReplace(vText, vBefore, vAfter)] C++: ___ [can use: repeated find and replace][also (case-insensitive): repeated find and std::search] 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)] Excel VBA: Replace [e.g. vTextNew = Replace(vText, vBefore, vAfter)] Go: Java: replace [e.g. vTextNew = vText.replace(vBefore, vAfter)] 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: 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)] Swift: replacingOccurrences [e.g. vText.replacingOccurrences(of:vBefore, with:vAfter)][requires: import Foundation] UFL: StrSplit [string to array (split by delimiters)][see also: StrSplitChars][note: can accept a multi-char string as a separator unless stated] 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 (std::stringstream): #include <sstream>] C#: Split [e.g. oArray = vText.Split(vSep)][note: blank delimiter: 1 output string (entire string)] Crystal: split [e.g. oArray = vText.split(vSep)] Excel: TEXTSPLIT [note: TEXTSPLIT (Excel 365)] Excel VBA: Split [e.g. oArray = Split(vText, vSep)][note: blank delimiter: 1 output string (entire string)] Go: Java: split [WARNING: splits based on RegEx, not a literal string][e.g. oArray = vText.split(vSep)][note: blank delimiter: 1 output string per char] 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: Ruby: split [e.g. oArray = vText.split(vSep)] Rust: split [e.g. oVec: Vec<&str> = vText.split(vSep).collect()] Swift: split [e.g. oArray = vText.split(separator:vSep).map{String($0)}][note: blank delimiter: 1 output string per char] 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 []] AutoHotkey: ___ [can use (find a char not in vText first): StrSplit(RegExReplace(vText, "(?<=.)(?=.)", vUnused), vUnused)][can use: 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#: ___ [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: Java: ___ [can use: String[] oArray = vText.codePoints().mapToObj(Character::toString).toArray(String[]::new)][also: vText.split("(?<=.)")][can use (WARNING: splits surrogate pairs): vText.split("")][WARNING: split blank string (for both approaches using split()): return array length 1] JavaScript: ___ [can use: [...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: vText.codePoints().mapToObj{Character.toString(it)}.toList().toTypedArray()][can use (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: 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: list(vText)][note: split blank string: return array length 0] R: 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>>()] Swift: ___ [can use: Array(vText).map{String($0)}][note: split blank string: return array length 0] UFL: StrChunk [or StrSplitLen][string to array (split into chunks of n chars)][see also: Array.Chunk/RegExReplace][workaround: RegExReplace and StrSplit] 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: Ruby: ___ Rust: ___ [can use: oVec = vText.chars().collect::<Vec<char>>().chunks(vCount).map(|v| v.iter().collect::<String>()).collect::<Vec<String>>()] Swift: ___ UFL: (StrHatch) [add a separator every n chars] 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: ___ 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: 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)] Ruby: ___ [can use: oArray.join(vSep)] Rust: ___ [can use: oArray.join(vSep)] Swift: ___ [can use: oArray.joined(separator:vSep)] UFL: StrContains [see also: StrEquals/StrStarts/StrEnds] AutoHotkey: InStr [note: 1-based][WARNING: case-insensitive by default] C++: ___ C#: Contains Crystal: includes [e.g. vText.includes?(vNeedle)] Excel: ___ [can use: =IFERROR(FIND(vNeedle,A1)>0,0)][note: FIND returns #VALUE! error if fails] Excel VBA: InStr [note: 1-based] Go: Java: contains JavaScript: includes Kotlin: contains PHP: str_contains Python: ___ R: Ruby: include [e.g. vText.include?(vNeedle)] Rust: contains Swift: contains UFL: InStr [search left-to-right][WARNING: languages may use 0-based/1-based string indexes][see also: IntStrRev/StrContains] AutoHotkey: InStr [note: 1-based, returns 0 if fails][WARNING: case-insensitive by default] C++: find [note: returns string::npos if fails][also (case-insensitive, forwards or backwards): std::search][also: strstr/wcsstr] C#: IndexOf [note: returns -1 if fails] Crystal: index [e.g. vText.index(vNeedle)][note: returns nil if fails] Excel: FIND [note: 1-based, returns #VALUE! error if fails] Excel VBA: InStr [note: 1-based, returns 0 if fails][e.g. InStr(1, vText, vNeedle)] Go: Java: indexOf [note: returns -1 if fails] JavaScript: indexOf [note: returns -1 if fails] Kotlin: indexOf [note: returns -1 if fails] PHP: mb_strpos [also (case-insensitive): mb_stripos][WARNING: returns false if fails][also (bytes): strpos, stripos][note: strpos v. strrpos] Python: str.find [note: returns -1 if fails][note: str.index throws if fails] R: Ruby: index [e.g. vText.index(vNeedle)][note: returns nil if fails] Rust: find [e.g. vText.find(vNeedle).unwrap()] Swift: ___ UFL: IntStrRev [search right-to-left][WARNING: languages may use 0-based/1-based string indexes][see also: IntStr/StrContains] AutoHotkey: InStr [note: 1-based, returns 0 if fails][WARNING: case-insensitive by default] C++: rfind [note: returns string::npos if fails][also (case-insensitive, forwards or backwards): std::search] C#: LastIndexOf [note: returns -1 if fails] Crystal: rindex [e.g. vText.rindex(vNeedle)][note: returns nil if fails] 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 fails] Excel VBA: InStrRev [note: 1-based, returns 0 if fails][e.g. InStrRev(vText, vNeedle)] Go: Java: lastIndexOf [note: returns -1 if fails] JavaScript: lastIndexOf [note: returns -1 if fails] Kotlin: lastIndexOf [note: returns -1 if fails][note: don't confuse with indexOfLast] PHP: mb_strrpos [also (case-insensitive): mb_strripos][WARNING: returns false if fails][also (bytes): strrpos, strripos][note: strpos v. strrpos] Python: str.rfind [note: returns -1 if fails][note: str.rindex throws if fails] R: Ruby: rindex [e.g. vText.rindex(vNeedle)][note: returns nil if fails] Rust: rfind [e.g. vText.rfind(vNeedle).unwrap()] Swift: ___ UFL: StrStarts [or StrStartsWith][see also: StrEquals/StrContains/StrEnds] AutoHotkey: ___ C++: starts_with [also: strncmp/wcsncmp] C#: StartsWith Crystal: starts_with [e.g. vText.starts_with?(vNeedle)] Excel: ___ Excel VBA: ___ Go: Java: startsWith JavaScript: startsWith Kotlin: startsWith PHP: str_starts_with Python: str.startswith R: Ruby: start_with [e.g. vText.start_with?(vNeedle)] Rust: starts_with Swift: hasPrefix UFL: StrEnds [or StrEndsWith][see also: StrEquals/StrContains/StrStarts] AutoHotkey: ___ C++: ends_with C#: EndsWith Crystal: ends_with [e.g. vText.ends_with?(vNeedle)] Excel: ___ Excel VBA: ___ Go: Java: endsWith JavaScript: endsWith Kotlin: endsWith PHP: str_ends_with Python: str.endswith R: Ruby: end_with [e.g. vText.end_with?(vNeedle)] Rust: ends_with Swift: hasSuffix UFL: RegExNew [or StrToRegEx][string to RegEx object] AutoHotkey: ___ [note: AutoHotkey stores RegEx needles as strings] C++: std::regex [e.g. std::regex oRegEx(vNeedle)] 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: Java: compile [e.g. Pattern oRegEx = Pattern.compile(vNeedle)][requires: import java.util.regex.Pattern] JavaScript: RegExp [e.g. oRegEx = new RegExp(vNeedle)] Kotlin: Regex [e.g. oRegEx = Regex(vNeedle)] PHP: ___ [note: PHP stores RegEx needles as strings] Python: compile [e.g. oRegEx = re.compile(vNeedle)][requires: import re] R: Ruby: Regexp.new [e.g. oRegEx = Regexp.new(vNeedle)] Rust: Regex::new [e.g. oRegEx = Regex::new(vNeedle).unwrap()][requires: use regex::Regex] Swift: Regex [e.g. oRegEx = try Regex(vNeedle)] UFL: RegExMatch [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 fails] C++: std::regex_search [e.g. 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 oMatch.Success: vPos = oMatch.Index][beforehand: oMatch = Regex.Match(vText, vNeedle)][WARNING: Regex.Match(vText, vNeedle).Index returns 0 on failure, 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 fails] Excel: ___ Excel VBA: ___ [can 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: 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 fails] Kotlin: find [e.g. if a match found: vPos = oMatch.range.start][beforehand (returns null if fails): 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): $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 fails] R: Ruby: index [e.g. vPos = vText.index(oRegEx)][also: vPos = vText =~ oRegEx][note: returns nil if fails] Rust: find [e.g. an optional containing the offset or None: oPos = oRegEx.find(vText)][note: offsets are in bytes] Swift: firstMatch [e.g. if oMatch is not nil: vPos = vText.distance(from:vText.startIndex, to:oMatch!.range.lowerBound)][beforehand: oMatch = try oRegEx.firstMatch(in:vText)] UFL: (RegExMatchDemo) [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-based, returns 0 if fails] 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 on failure, 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: 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 fails] 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: 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] 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: (RegExMatchWhole) [has to match the whole string][workaround: use '^' and '$' anchors] AutoHotkey: ___ C++: std::regex_match [note: whole-string match] 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 R: Ruby: ___ [can use (with '^'/'$' anchors): vText.match?(oRegEx)] Rust: ___ Swift: wholeMatch UFL: RegExMatchAll [find all matches][e.g. return an array][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: Java: ___ [can use: find repeatedly] JavaScript: matchAll Kotlin: findAll PHP: preg_match_all Python: re.findall [also: re.split] R: Ruby: scan [e.g. vText.scan(oRegEx)] Rust: find_iter 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: Java: replaceAll JavaScript: replace Kotlin: replace PHP: preg_replace [also: mb_ereg_replace][note: 'preg' = Perl, 'ereg' = POSIX] Python: re.sub R: 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()] Swift: replacingOccurrences [also: stringByReplacingMatchesInString] UFL: RegExEscape [or StrEscape][add escape characters to treat all characters literally, rather than treat some as metacharacters] AutoHotkey: ___ C++: ___ C#: Regex.Escape Crystal: Regex.escape [e.g. Regex.escape(vText)][also: vText.dump][also: vText.inspect] Excel: ___ Excel VBA: ___ Go: Java: ___ JavaScript: ___ Kotlin: Regex.escape PHP: preg_quote Python: re.escape R: Ruby: Regexp.escape [e.g. Regexp.escape(vText)][also: vText.dump][also: vText.inspect] Rust: regex::escape [e.g. regex::escape(vText)] Swift: ___ 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): SubStr(vText, vPos, vCount)] C++: substr [e.g. (UTF-8 bytes): vText.substr(vPos, vCount)][WARNING: substr uses bytes, so can frequently split within a char] C#: Substring [e.g. (UTF-16 shorts): vText.Substring(vPos, vCount)] Crystal: ___ [can use (codepoints): vText[vPos...vPos+vCount]] Excel: MID [e.g. (UTF-16 shorts): MID(A1,vPos,vCount)] Excel VBA: Mid [e.g. (UTF-16 shorts): Mid(vText, vPos, vCount)][note: unlike Excel sheet function, can omit count parameter] Go: Java: ___ [can use (UTF-16 shorts): vText.substring(vPos, vPos+vCount)] JavaScript: ___ [can use (UTF-16 shorts): vText.slice(vPos, vPos+vCount)][deprecated: substr(vPos, vCount)][note: don't confuse with substring(vPos1, vPos2)] Kotlin: ___ [can use (UTF-16 shorts): vText.slice(vPos..<vPos+vCount)] PHP: mb_substr [e.g. (codepoints): mb_substr($vText, $vPos, $vCount)][WARNING: substr uses bytes, so can frequently split within a char] Python: ___ [can use (codepoints): vText[vPos:vPos+vCount]] R: Ruby: slice [e.g. vText.slice(vPos, vCount)][also: vText[vPos...vPos+vCount]] Rust: ___ [can use (codepoints): vTextNew: String = vText.chars().skip(vPos).take(vCount).collect()] Swift: ___ [can use (codepoints): String(Array(vText)[vPos..<vPos+vCount])] UFL: (StrSliceExc) [substring using pos1/pos2 (exclusive end)][WARNING: languages may use 0-based/1-based string indexes] AutoHotkey: ___ [can use: SubStr(vText, vPos1, vPos2-vPos1)] C++: ___ [can use: vText.substr(vPos1, vPos2-vPos1)] C#: ___ [can use: vText.Substring(vPos1, vPos2-vPos1)] Crystal: ___ [can use: vText[vPos1...vPos2]] Excel: ___ [can use: MID(A1,vPos1,vPos2-vPos1)] Excel VBA: ___ [can use: Mid(vText, vPos1, vPos2 - vPos1)] Go: Java: substring [e.g. vText.substring(vPos1, vPos2)][WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: slice [e.g. vText.slice(vPos1, vPos2)][also: substring(vPos1, vPos2)][note: don't confuse with (deprecated) substr(vPos, vCount)] Kotlin: slice [e.g. vText.slice(vPos1..<vPos2)][also: substring][deprecated: subSequence] PHP: ___ [can use: mb_substr($vText, $vPos1, $vPos2-$vPos1)] Python: ___ [can use: vText[vPos1:vPos2]][note: vText[start:end:step]] R: Ruby: slice [e.g. 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()] 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] AutoHotkey: ___ [can use: SubStr(vText, vPos1, vPos2-vPos1+1)] C++: ___ [can use: vText.substr(vPos1, vPos2-vPos1+1)] C#: ___ [can use: vText.Substring(vPos1, vPos2-vPos1+1)] Crystal: ___ [can use: vText[vPos1..vPos2]] Excel: ___ [can use: MID(A1,vPos1,vPos2-vPos1+1)] Excel VBA: ___ [can use: Mid(vText, vPos1, vPos2 - vPos1 + 1)] Go: Java: ___ [can use: vText.substring(vPos1, vPos2+1)][WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: ___ [can use: vText.slice(vPos1, vPos2+1)] Kotlin: slice [e.g. vText.slice(vPos1..vPos2)] PHP: ___ [can use: mb_substr($vText, $vPos1, $vPos2-$vPos1+1)] Python: ___ [can use: vText[vPos1:vPos2+1]] R: Ruby: slice [e.g. 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()] Swift: ___ [can use: 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] AutoHotkey: ___ [can use: SubStr(vText, 1, vCount)] C++: ___ [can use: vText.substr(0, vCount)] C#: ___ [can use: vText.Substring(0, Math.Min(vCount, vText.Length))] Crystal: ___ [can use: vText[...vCount]] Excel: LEFT [e.g. LEFT(A1,vCount)][note: omit Count same as Count 1] Excel VBA: Left [e.g. Left(vText, vCount)][note: can't omit Count] Go: Java: ___ [can use: vText.substring(0, Math.min(vCount, vText.length()))][WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: ___ [can use: vText.slice(0, vCount)][also: substring][note: don't confuse with (deprecated) substr(vPos, vCount)] Kotlin: take [e.g. vText.take(vCount)] PHP: ___ [can use: mb_substr($vText, 0, $vCount)] Python: ___ [can use: vText[:vCount]] R: Ruby: slice [e.g. vText.slice(0, vCount)][also: vText.slice(...vCount)][also: vText[...vCount]] Rust: ___ [can use: vText.chars().take(vCount).collect()] Swift: prefix [e.g. vText.prefix(vCount)] UFL: (StrRight) [or StrTakeRight/StrTakeLast][get the last n chars] AutoHotkey: ___ [can use: SubStr(vText, -vCount)][note: AHK v1: SubStr(vText, -vCount+1)] C++: ___ [can use: vText.substr(vCount<vText.size()?vText.size()-vCount:0)][also: vText.substr(std::max<int>(vText.size()-vCount, 0))][requires (std::max): #include <algorithm>] C#: ___ [can use: vText.Substring(Math.Max(vText.Length-vCount, 0))] Crystal: ___ [can use: vText[-vCount..]] Excel: RIGHT [e.g. RIGHT(A1,vCount)][note: omit Count same as Count 1] Excel VBA: Right [e.g. Right(vText, vCount)][note: can't omit Count] Go: Java: ___ [can use: vText.substring(Math.max(vText.length()-vCount, 0))][WARNING: pos1/pos2 ('substr'/'substring' is often pos/count)] JavaScript: ___ [can use: vText.slice(-vCount)][also: substring] Kotlin: takeLast [e.g. vText.takeLast(vCount)] PHP: ___ [can use: mb_substr($vText, -$vCount)] Python: ___ [can use: vText[-vCount:]] R: Ruby: slice [e.g. vText.slice(-vCount..)][also: vText[-vCount..]] Rust: ___ [can use: vText.chars().skip(vText.len()-vCount).collect()] Swift: suffix [e.g. vText.suffix(vCount)] UFL: (StrDropLeft) [or StrDropFirst][remove the first n chars] 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: 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: Ruby: slice [e.g. vText.slice(vCount..)][also: vText[vCount..]] Rust: ___ [can use: vTextNew: String = vText.chars().skip(vCount).collect()] 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: 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: Ruby: slice [e.g. vText.slice(...-vCount)][also: vText[...-vCount]] Rust: ___ [can use: vTextNew: String = vText.chars().take(vText.len()-vCount).collect()] 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: 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: Ruby: slice [e.g. vText.slice(vCount1...-vCount2)][also: vText[vCount1...-vCount2]] Rust: ___ [can use: vTextNew: String = vText.chars().skip(vCount1).take(vText.len()-vCount1-vCount2).collect()] Swift: ___ [can use: vTextNew = String(vText.dropFirst(vCount1).dropLast(vCount2))] 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: ___ Swift: ___ UFL: (StrAlphabetize) [or StrAlphabetise][alphabetise characters in string] AutoHotkey: ___ C++: std::sort C#: ___ Crystal: ___ [can use: vText.chars.sort.join][also (case-insensitive): vText.chars.sort{|v1,v2| v1.downcase <=> v2.downcase}.join][also (case-insensitive): vText.chars.sort{|v1,v2| v1.to_s.compare(v2.to_s, true)}.join] Excel: ___ Excel VBA: ___ Go: Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: Ruby: ___ [can use: vText.chars.sort.join][also (case-insensitive): vText.chars.sort(&:casecmp).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>();] Swift: ___ UFL: (StrReverse) [reverse characters in string] AutoHotkey: ___ C++: std::reverse C#: ___ Crystal: reverse [e.g. vTextNew = vText.reverse] Excel: ___ Excel VBA: StrReverse Go: Java: reverse JavaScript: ___ [can use: vTextNew = [...vText].reverse().join("")][note: 'Strings are iterated by Unicode code points.'][also (WARNING: 'messes up' any surrogate pairs): vTextNew = vText.split("").reverse().join("")] Kotlin: reversed PHP: strrev Python: ___ R: Ruby: reverse [e.g. vTextNew = vText.reverse] Rust: rev [e.g. vTextNew: String = vText.chars().rev().collect()] Swift: reversed [e.g. vTextNew = String(vText.reversed())] 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: Java: Collections.shuffle 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: Ruby: shuffle [e.g. vText.chars.shuffle.join] Rust: ___ [can use (shuffle): 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] 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: 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: 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] Swift: ___/___/___ [note: trimmingCharacters only handles whitespace] 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: Ruby: ___ Rust: ___ 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: Ruby: ___ Rust: ___ Swift: ___ UFL: Format [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/FormatPad] AutoHotkey: Format [e.g. Format("{} {} {:.3f}", 123, "abc", 456.7891)] C++: std::format [e.g. std::format("{} {} {:.3f}", (double)123, "abc", 456.7891)][also: sprintf/vsprintf][requires (format): #include <format>][WARNING: used '(double)vInt' to suppress error message] 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] 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)] 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: FormatPad [or StrPadZero][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}", (double)12)][requires (format): #include <format>][WARNING: used '(double)vInt' to suppress error message] 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)] 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] 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: 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: +] R: ___ [can use: 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] Swift: ___ [can use: +] UFL: StrPadLeft [e.g. pad 'abc' with 3 chars (padding on the left)][WARNING: pad left = justify right][see also: StrRept/FormatPad] 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")] 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")] 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")] Swift: ___ UFL: StrSpan/StrCompSpan [span / complementary span e.g. count the leading whitespace chars] 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: ___/___ Swift: ___/___ UFL: StrIsDigit [string contains ASCII digit chars (0-9) only, string can be blank] AutoHotkey: IsDigit C++: ___ C#: ___ Crystal: ___ [FIXME] Excel: ___ [can use: ISNUMBER(VALUE(A1))][WARNING: works consistently with 1-char strings, but for longer strings accepts '-'/'.' etc also] Excel VBA: ___ [can use (for first char of string): vText Like "#*"] Go: Java: ___ JavaScript: ___ [can use: vIsDigit = /^\d*$/.test(vText)] Kotlin: ___ [FIXME] PHP: ctype_digit Python: isdigit R: Ruby: ___ [FIXME] Rust: ___ [can use: vText.chars().all(|v|v.is_ascii_digit())] Swift: ___ [FIXME] UFL: CharIsDigit [char is an ASCII digit (0-9)] AutoHotkey: IsDigit [note: for strings] C++: isdigit C#: Char.IsDigit Crystal: ascii_number [e.g. 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 first char of string): vText Like "#*"] Go: Java: Character.isDigit JavaScript: ___ [can use (for strings): vIsDigit = /^\d*$/.test(vText)] Kotlin: Character.isDigit PHP: ctype_digit [note: for strings] Python: isdigit [note: for strings] R: Ruby: ___ Rust: is_ascii_digit [WARNING: is_digit allows digits *and letters*] Swift: isNumber [e.g. vChar.isNumber] UFL: StrIsAlpha [string contains ASCII letter chars (A-Z/a-z) only, string can be blank] AutoHotkey: IsAlpha C++: ___ C#: ___ Crystal: ___ [FIXME] 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): vText Like "[A-Za-z]*"] Go: Java: ___ JavaScript: ___ [can use: vIsAlpha = /^[A-Za-z]*$/.test(vText)] Kotlin: ___ [FIXME] PHP: ctype_alpha Python: isalpha R: Ruby: ___ [FIXME] Rust: ___ [can use: vText.chars().all(|v|v.is_ascii_alphabetic())] Swift: ___ [FIXME] UFL: CharIsAlpha [char is an ASCII letter (A-Z/a-z)] AutoHotkey: IsAlpha [note: for strings] C++: isalpha C#: Char.IsLetter Crystal: ascii_letter [e.g. 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 first char of string): vText Like "[A-Za-z]*"] Go: Java: Character.isLetter JavaScript: ___ [can use (for strings): vIsAlpha = /^[A-Za-z]*$/.test(vText)] Kotlin: Character.isLetter PHP: ctype_alpha [note: for strings] Python: isalpha [note: for strings] R: Ruby: ___ Rust: is_ascii_alphabetic Swift: isLetter [e.g. vChar.isLetter] UFL: StrIsAscii [string contains ASCII chars (0-127) only, string can be blank] AutoHotkey: ___ [can use: vIsAscii := !RegExMatch(vText, "[^[:ascii:]]")][can use: DllCall with WideCharToMultiByte and codepage 20127 (us-ascii)] C++: ___ C#: ___ Crystal: ascii_only [e.g. vText.ascii_only?] Excel: ___ [can use (for first char of string): CODE(A1)<128] Excel VBA: ___ [can use (for first char of string): AscW(vText) < 128] Go: 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")] Python: isascii [e.g. vText.isascii()] R: Ruby: ascii_only [e.g. vText.ascii_only?] Rust: is_ascii [e.g. vText.is_ascii()] 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 string): vIsAscii := !RegExMatch(vText, "[^[:ascii:]]")][can use (for string): DllCall with WideCharToMultiByte and codepage 20127 (us-ascii)] C++: isascii C#: Char.IsAscii Crystal: ascii [e.g. vChar.ascii?] Excel: ___ [can use (for first char of string): CODE(A1)<128] Excel VBA: ___ [can use (for first char of string): AscW(vText) < 128] Go: 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 string): $vIsAscii = !preg_match("/[^\x00-\x7F]/", $vText)][also (for string): $vIsAscii = mb_check_encoding($vText, "ASCII")] Python: isascii [e.g. vText.isascii()][note: for strings] R: Ruby: ascii_only [e.g. vText.ascii_only?][note: for strings] Rust: is_ascii [e.g. vChar.is_ascii()] Swift: isASCII [e.g. 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: Ruby: ___ Rust: ___ Swift: ___ UFL: ChrUnused [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: ___ 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: ___ 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: ___ Swift: ___ UFL: (StrInsert) [insert string (modify string)] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: insert [e.g. vText1.insert(vPos, vText2)] Rust: ___ Swift: ___ UFL: (StrInserted) [insert string (modify string)] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: ___ 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: Ruby: ___ [can use: +=][also: <<][also: concat][WARNING: concat() modifies the string] Rust: ___ [can use: +=] Swift: ___ [can use: +=][also: append][WARNING: append() modifies the string] UFL: (StrOverwrite) [overwrite string (modify string)] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: ___ [also: setbyte] Rust: ___ Swift: ___ UFL: (StrOverwritten) [overwrite string (return new string)] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: ___ Rust: ___ 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] AutoHotkey: ___ C++: ___ C#: ___ Crystal: ___ [can use: succ] Excel: ___ Excel VBA: ___ Go: ___ Java: ___ JavaScript: ___ Kotlin: ___ PHP: ___ Python: ___ R: ___ Ruby: ___ [can use: succ][also (alias for succ): next][also (multiple strings): upto] Rust: ___ 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/IntStrRev [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/IntStrRev 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: RegExMatch [find offset of first match, get text of any substrings][WARNING: languages may use 0-based/1-based string indexes] format: RegExMatch(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) 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):

[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 [Swift] String Format Specifiers String Format Specifiers What are the supported Swift String format specifiers? - Stack Overflow

Links (Escape Characters):

[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 [Swift] Strings and Characters | Documentation Character | Apple Developer Documentation