or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

async-programming.mdcharacter-operations.mdcollections.mdconfiguration.mdcore-infrastructure.mddata-encoding.mddate-time.mdexternal-integration.mdindex.mdnumeric-types.mdreactive-programming.mdstring-operations.mdtype-system.md
tile.json

string-operations.mddocs/

String Operations

Comprehensive string manipulation, regular expression processing, and character operations with full .NET String API compatibility and Unicode support.

String Module - String Manipulation

Rich string manipulation capabilities matching the .NET String API, providing extensive text processing functions.

Enums and Types

StringComparison

enum StringComparison {
    CurrentCulture = 0,
    CurrentCultureIgnoreCase = 1,
    InvariantCulture = 2,
    InvariantCultureIgnoreCase = 3,
    Ordinal = 4,
    OrdinalIgnoreCase = 5
}

Printf Interfaces

interface IPrintfFormat {
    input: string;
    cont: IPrintfFormatContinuation;
}

interface IPrintfFormatContinuation {
    // Continuation type for printf formatting
}

Comparison Functions

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")); // < 0

String Analysis

Functions 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')

String Transformation

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"

String Generation

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"

String Splitting and Filtering

// 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"

GUID Operations

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); // true

Base64 Operations

Encode 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"

Printf Functions

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"

RegExp Module - Regular Expression Utilities

Regular expression creation, matching, and manipulation with .NET Regex compatibility.

Core Functions

// 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

Pattern Matching

// 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"]]

String Operations

// 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"]

Char Module - Character Operations

Character classification and manipulation using comprehensive Unicode support.

Character Classification

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 category

Surrogate Pair Support

Handle 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

Character Conversion

// 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"

Parsing and Validation

// 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)

Advanced Character Processing

Text Processing Pipeline

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}

Unicode Text Processing

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