Comprehensive string manipulation, regular expression processing, and character operations with full .NET String API compatibility and Unicode support.
Rich string manipulation capabilities matching the .NET String API, providing extensive text processing functions.
enum StringComparison {
CurrentCulture = 0,
CurrentCultureIgnoreCase = 1,
InvariantCulture = 2,
InvariantCultureIgnoreCase = 3,
Ordinal = 4,
OrdinalIgnoreCase = 5
}interface IPrintfFormat {
input: string;
cont: IPrintfFormatContinuation;
}
interface IPrintfFormatContinuation {
// Continuation type for printf formatting
}String comparison with culture and case sensitivity options.
// Multi-overload comparison function
function compare(...args: any[]): number;
// Ordinal comparison (byte-by-byte)
function compareOrdinal(x: string, y: string): number;
// Instance comparison
function compareTo(x: string, y: string): number;
// Usage
import { compare, compareOrdinal, StringComparison } from "fable-library/String.js";
// Different comparison modes
console.log(compare("apple", "APPLE", StringComparison.Ordinal)); // > 0
console.log(compare("apple", "APPLE", StringComparison.OrdinalIgnoreCase)); // 0
console.log(compareOrdinal("apple", "banana")); // < 0Functions to analyze string content and structure.
// Pattern matching
function startsWith(str: string, pattern: string, ic: number): boolean;
function endsWith(str: string, search: string): boolean;
// Null/empty checking
function isNullOrEmpty(str: string | any): boolean;
function isNullOrWhiteSpace(str: string | any): boolean;
// Character searching
function indexOfAny(str: string, anyOf: string[], ...args: number[]): number;
// Usage
import {
startsWith, endsWith, isNullOrEmpty,
isNullOrWhiteSpace, indexOfAny, StringComparison
} from "fable-library/String.js";
const text = "Hello World";
console.log(startsWith(text, "Hello", StringComparison.Ordinal)); // true
console.log(endsWith(text, "World")); // true
console.log(isNullOrEmpty("")); // true
console.log(isNullOrEmpty(null)); // true
console.log(isNullOrWhiteSpace(" ")); // true
console.log(indexOfAny("Hello", ["e", "o"])); // 1 (first 'e')Functions to modify and transform strings.
// Insertion and removal
function insert(str: string, startIndex: number, value: string): string;
function remove(str: string, startIndex: number, count?: number): string;
// Replacement
function replace(str: string, search: string, replace: string): string;
// Trimming
function trim(str: string, ...chars: string[]): string;
function trimStart(str: string, ...chars: string[]): string;
function trimEnd(str: string, ...chars: string[]): string;
// Padding
function padLeft(str: string, len: number, ch?: string, isRight?: boolean): string;
function padRight(str: string, len: number, ch?: string): string;
// Usage
import {
insert, remove, replace, trim, trimStart,
padLeft, padRight
} from "fable-library/String.js";
const text = "Hello World";
console.log(insert(text, 5, " Beautiful")); // "Hello Beautiful World"
console.log(remove(text, 5, 6)); // "Hello"
console.log(replace(text, "World", "Universe")); // "Hello Universe"
const padded = " Hello ";
console.log(trim(padded)); // "Hello"
console.log(trimStart(padded)); // "Hello "
console.log(trimEnd(padded)); // " Hello"
console.log(padLeft("42", 5, "0")); // "00042"
console.log(padRight("42", 5, "0")); // "42000"Functions to create strings programmatically.
// Initialize with function
function initialize(n: number, f: (i: number) => string): string;
// Replicate string
function replicate(n: number, x: string): string;
// Join arrays/sequences
function join(delimiter: string, ...xs: any[]): string;
function joinWithIndices<T>(delimiter: string, xs: string[], startIndex: number, count: number): string;
// Usage
import { initialize, replicate, join, joinWithIndices } from "fable-library/String.js";
// Generate string by index
const indexed = initialize(5, i => `Item${i}`); // "Item0Item1Item2Item3Item4"
// Repeat string
const repeated = replicate(3, "Hello"); // "HelloHelloHello"
// Join arrays
const joined = join(", ", ["apple", "banana", "cherry"]); // "apple, banana, cherry"
// Join with range
const partial = joinWithIndices("-", ["a", "b", "c", "d", "e"], 1, 3); // "b-c-d"// Split strings
function split(str: string, splitters: string[], count?: number, removeEmpty?: number): string[];
// Filter characters
function filter(pred: (char: string) => boolean, x: string): string;
// Get character at index
function getCharAtIndex(input: string, index: number): string;
// Usage
import { split, filter, getCharAtIndex } from "fable-library/String.js";
const text = "apple,banana;cherry:date";
// Split by multiple delimiters
const parts = split(text, [",", ";", ":"]);
console.log(parts); // ["apple", "banana", "cherry", "date"]
// Filter characters
const onlyVowels = filter(c => "aeiou".includes(c.toLowerCase()), "Hello World");
console.log(onlyVowels); // "eoo"
// Get character
console.log(getCharAtIndex("Hello", 1)); // "e"Generate and manipulate GUIDs (UUIDs).
// GUID validation
function validateGuid(str: string, doNotThrow?: boolean): string | [boolean, string];
// Generate new GUID
function newGuid(): string;
// GUID conversion
function guidToArray(s: string): Uint8Array;
function arrayToGuid(buf: ArrayLike<number>): string;
// Usage
import { newGuid, validateGuid, guidToArray, arrayToGuid } from "fable-library/String.js";
// Generate GUID
const guid = newGuid();
console.log(guid); // "12345678-1234-1234-1234-123456789abc"
// Validate GUID
const [isValid, cleanGuid] = validateGuid(guid, true) as [boolean, string];
console.log(isValid); // true
// Convert to bytes and back
const bytes = guidToArray(guid);
const restored = arrayToGuid(bytes);
console.log(restored === guid); // trueEncode and decode Base64 strings.
// Base64 encoding/decoding
function toBase64String(inArray: number[]): string;
function fromBase64String(b64Encoded: string): Uint8Array;
// Usage
import { toBase64String, fromBase64String } from "fable-library/String.js";
const data = [72, 101, 108, 108, 111]; // "Hello" in ASCII
const encoded = toBase64String(data);
console.log(encoded); // "SGVsbG8="
const decoded = fromBase64String(encoded);
console.log(Array.from(decoded)); // [72, 101, 108, 108, 111]
console.log(String.fromCharCode(...decoded)); // "Hello"F#-style printf formatting system.
// Printf format creation
function printf(input: string): IPrintfFormat;
// Output targets
function toConsole(arg: IPrintfFormat): Function;
function toConsoleError(arg: IPrintfFormat): Function;
function toText(arg: IPrintfFormat): Function;
function toFail(arg: IPrintfFormat): Function;
// Simple formatting
function fsFormat(str: string): Function;
function format(str: string, ...args: any[]): string;
// Usage
import { printf, toConsole, toText, format, fsFormat } from "fable-library/String.js";
// F# style formatting
const formatter = printf("Hello %s, you are %d years old");
const consoleOut = toConsole(formatter);
consoleOut("John", 30); // Prints: "Hello John, you are 30 years old"
const textFormatter = toText(formatter);
const result = textFormatter("Alice", 25); // Returns: "Hello Alice, you are 25 years old"
// Simple formatting
const formatted = format("Value: {0}, Count: {1}", 42, 10);
console.log(formatted); // "Value: 42, Count: 10"
// F# format function
const fsharpFormatter = fsFormat("Processing item %d of %d");
console.log(fsharpFormatter(5, 10)); // "Processing item 5 of 10"Regular expression creation, matching, and manipulation with .NET Regex compatibility.
// Create regex with options
function create(pattern: string, options?: number): RegExp;
// Escape special characters
function escape(str: string): string;
// Simple matching
function isMatch(str: string, pattern: string, options?: number): boolean;
// Usage
import { create, escape, isMatch } from "fable-library/RegExp.js";
// Create regex patterns
const emailPattern = create("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b", 1); // Case insensitive
// Escape special characters
const escaped = escape("How much? $5.00 (approx.)");
console.log(escaped); // "How much\\? \\$5\\.00 \\(approx\\.\\)"
// Simple matching
console.log(isMatch("test@example.com", "\\b\\w+@\\w+\\.\\w+\\b")); // true
console.log(isMatch("not-an-email", "\\b\\w+@\\w+\\.\\w+\\b")); // false// Single match
function match(str: string, pattern: string, options?: number): string[];
// Multiple matches
function matches(str: string, pattern: string, options?: number): string[][];
// Usage
import { match, matches } from "fable-library/RegExp.js";
const text = "Call me at 123-456-7890 or 987-654-3210";
const phonePattern = "\\d{3}-\\d{3}-\\d{4}";
// First match only
const firstMatch = match(text, phonePattern);
console.log(firstMatch); // ["123-456-7890"]
// All matches
const allMatches = matches(text, phonePattern);
console.log(allMatches); // [["123-456-7890"], ["987-654-3210"]]
// With capturing groups
const urlText = "Visit https://example.com or http://test.org";
const urlPattern = "(https?)://([\\w.-]+)";
const urlMatches = matches(urlText, urlPattern);
console.log(urlMatches);
// [["https://example.com", "https", "example.com"],
// ["http://test.org", "http", "test.org"]]// Replace matches
function replace(str: string, pattern: string, replacement: string, options?: number): string;
// Split by pattern
function split(str: string, pattern: string, options?: number, count?: number): string[];
// Usage
import { replace, split } from "fable-library/RegExp.js";
const text = "The quick brown fox jumps over the lazy dog";
// Replace with pattern
const replaced = replace(text, "\\b\\w{4}\\b", "****");
console.log(replaced); // "The quick brown fox jumps **** the **** dog"
// Replace with capturing groups
const phoneText = "Call 123-456-7890";
const formatted = replace(phoneText, "(\\d{3})-(\\d{3})-(\\d{4})", "($1) $2-$3");
console.log(formatted); // "Call (123) 456-7890"
// Split by pattern
const csvLine = "apple,banana;cherry:date|grape";
const fruits = split(csvLine, "[,;:|]");
console.log(fruits); // ["apple", "banana", "cherry", "date", "grape"]
// Limited splits
const limitedSplit = split(csvLine, "[,;:|]", 0, 3);
console.log(limitedSplit); // ["apple", "banana", "cherry:date|grape"]Character classification and manipulation using comprehensive Unicode support.
Unicode-aware character classification functions.
// Unicode category
function getUnicodeCategory(str: string, index?: number): number;
// Basic character types
function isControl(str: string, index?: number): boolean;
function isDigit(str: string, index?: number): boolean;
function isLetter(str: string, index?: number): boolean;
function isLetterOrDigit(str: string, index?: number): boolean;
function isUpper(str: string, index?: number): boolean;
function isLower(str: string, index?: number): boolean;
function isNumber(str: string, index?: number): boolean;
function isPunctuation(str: string, index?: number): boolean;
function isSeparator(str: string, index?: number): boolean;
function isSymbol(str: string, index?: number): boolean;
function isWhiteSpace(str: string, index?: number): boolean;
// Usage
import {
isLetter, isDigit, isUpper, isLower,
isWhiteSpace, isPunctuation, getUnicodeCategory
} from "fable-library/Char.js";
const text = "Hello123! ";
console.log(isLetter("H")); // true
console.log(isDigit("1")); // true
console.log(isUpper("H")); // true
console.log(isLower("e")); // true
console.log(isPunctuation("!")); // true
console.log(isWhiteSpace(" ")); // true
// Work with string indices
console.log(isLetter(text, 0)); // true ('H')
console.log(isDigit(text, 5)); // true ('1')
console.log(isPunctuation(text, 8)); // true ('!')
// Unicode categories
console.log(getUnicodeCategory("A")); // Uppercase letter category
console.log(getUnicodeCategory("1")); // Decimal number categoryHandle Unicode surrogate pairs correctly.
// Surrogate pair detection
function isHighSurrogate(str: string, index?: number): boolean;
function isLowSurrogate(str: string, index?: number): boolean;
function isSurrogate(str: string, index?: number): boolean;
// Usage
import { isHighSurrogate, isLowSurrogate, isSurrogate } from "fable-library/Char.js";
// Emoji or high Unicode character that uses surrogate pairs
const emoji = "💻"; // Computer emoji
const highSurrogate = emoji.charCodeAt(0);
const lowSurrogate = emoji.charCodeAt(1);
console.log(isHighSurrogate(String.fromCharCode(highSurrogate))); // true
console.log(isLowSurrogate(String.fromCharCode(lowSurrogate))); // true
console.log(isSurrogate(String.fromCharCode(highSurrogate))); // true// Case conversion
function toUpper(str: string): string;
function toLower(str: string): string;
// String conversion
function toString(char: string): string;
// Usage
import { toUpper, toLower, toString } from "fable-library/Char.js";
console.log(toUpper("hello")); // "HELLO"
console.log(toLower("WORLD")); // "world"
console.log(toString("A")); // "A"
// Handle Unicode properly
console.log(toUpper("café")); // "CAFÉ"
console.log(toLower("ÑOÑO")); // "ñoño"// Get numeric value of character
function getNumericValue(str: string, index?: number): number;
// ASCII checking
function isAscii(str: string, index?: number): boolean;
// Usage
import { getNumericValue, isAscii } from "fable-library/Char.js";
// Numeric values
console.log(getNumericValue("5")); // 5
console.log(getNumericValue("A")); // -1 (not numeric)
console.log(getNumericValue("Ⅴ")); // 5 (Roman numeral V)
// ASCII checking
console.log(isAscii("A")); // true
console.log(isAscii("@")); // true
console.log(isAscii("café", 3)); // false ('é' is not ASCII)
console.log(isAscii("💻")); // false (emoji)import {
isLetter, isDigit, toUpper, toLower,
isWhiteSpace, isPunctuation
} from "fable-library/Char.js";
import { filter, map } from "fable-library/String.js";
// Extract only letters and digits
function extractAlphanumeric(text: string): string {
return filter(c => isLetter(c) || isDigit(c), text);
}
// Normalize case for comparison
function normalizeText(text: string): string {
const lettersOnly = filter(c => isLetter(c) || isWhiteSpace(c), text);
return toLower(lettersOnly);
}
// Count character types
function analyzeText(text: string): object {
let letters = 0, digits = 0, punctuation = 0, whitespace = 0;
for (let i = 0; i < text.length; i++) {
if (isLetter(text, i)) letters++;
else if (isDigit(text, i)) digits++;
else if (isPunctuation(text, i)) punctuation++;
else if (isWhiteSpace(text, i)) whitespace++;
}
return { letters, digits, punctuation, whitespace };
}
// Usage
const sample = "Hello World! 123";
console.log(extractAlphanumeric(sample)); // "HelloWorld123"
console.log(normalizeText(sample)); // "hello world "
console.log(analyzeText(sample)); // {letters: 10, digits: 3, punctuation: 1, whitespace: 2}import {
getUnicodeCategory, isSurrogate,
toUpper, toLower
} from "fable-library/Char.js";
// Safe Unicode iteration (handles surrogate pairs)
function* iterateUnicodeCharacters(text: string) {
for (let i = 0; i < text.length; i++) {
if (isSurrogate(text, i) && i + 1 < text.length) {
yield text.substring(i, i + 2);
i++; // Skip the low surrogate
} else {
yield text[i];
}
}
}
// Unicode-aware text statistics
function getUnicodeStats(text: string): Map<number, number> {
const categoryCount = new Map<number, number>();
for (const char of iterateUnicodeCharacters(text)) {
const category = getUnicodeCategory(char);
categoryCount.set(category, (categoryCount.get(category) || 0) + 1);
}
return categoryCount;
}
// Usage
const unicodeText = "Hello 世界! 💻🌍";
const stats = getUnicodeStats(unicodeText);
console.log(stats); // Map with Unicode category counts