Skip to main content

StringUtils

StringUtils provides robust string operations that handle edge cases (null, undefined, wrong types) gracefully. Use it instead of vanilla string methods when working with data that might be unreliable.

Package: io-oidis-commons

import { StringUtils } from "@io-oidis-commons/.../Utils/StringUtils.js";

Validation​

StringUtils.IsEmpty($input : string) : boolean    // true if empty, null, or undefined
StringUtils.Length($input : string) : number // String length, or 0 if null/undefined
if (StringUtils.IsEmpty(record.Name)) {
LogIt.Warning("Name is empty");
}

const len = StringUtils.Length(userInput); // Safe — returns 0 for null

Search & Comparison​

StringUtils.Contains($input, ...$searchString) : boolean
StringUtils.ContainsIgnoreCase($input, ...$searchString) : boolean
StringUtils.StartsWith($input, $searchString) : boolean
StringUtils.EndsWith($input, $searchString) : boolean
StringUtils.IndexOf($input, $searchString, $fromStart?, $offset?) : number
StringUtils.OccurrenceCount($input, $searchFor) : number
StringUtils.PatternMatched($pattern, $value) : boolean
Variadic search

Contains and ContainsIgnoreCase are variadic — they accept multiple search strings and return true if any of them is found:

// Returns true if EAN contains "859" OR "860" OR "861"
StringUtils.Contains(record.EAN, "859", "860", "861");

Examples:

if (StringUtils.Contains(record.EAN, "859")) {
// EAN contains "859"
}

if (StringUtils.StartsWith(filename, "Report_")) {
// Filename starts with "Report_"
}

// Find position of substring
const pos = StringUtils.IndexOf(path, "/api/"); // → index or -1

// Search from end
const lastPos = StringUtils.IndexOf(path, "/", false); // fromStart = false

// Count occurrences
const count = StringUtils.OccurrenceCount(csv, ","); // → number of commas
Hot paths — prefer native

StartsWith / EndsWith are null-safe wrappers. In hot paths (request handling, routing, parsers, large payloads) prefer native startsWith / endsWith and guard a nullable value first:

const url : string = ObjectValidator.IsString($request.url) ? $request.url : "";
if (url.startsWith("/api/")) { /* ... */ }

For short metadata (headers, short paths) the wrapper is perfectly fine. Historically these helpers did a full-input scan via Contains (~1000× slower than native on large no-match inputs); fixed in OID-363 to delegate to native.

Wildcard Pattern Matching​

PatternMatched supports * wildcard characters and accepts single patterns or arrays:

// Single pattern with wildcard
StringUtils.PatternMatched("*.Controller", className); // true for "MyApp.UserController"
StringUtils.PatternMatched("Io.Oidis.*", namespace); // true for "Io.Oidis.Hub.AuthManager"

// Array of patterns — true if ANY matches
StringUtils.PatternMatched(["*.Controller", "*.Manager"], className);

Manipulation​

StringUtils.Replace($input, $search, $replacement) : string
StringUtils.Remove($input, ...$searchString) : string
StringUtils.Split($input, ...$splitBy) : string[]
StringUtils.Substring($input, $start, $end?) : string
StringUtils.Format($template, ...args) : string
StringUtils.StripSlashes($input) : string
StringUtils.StripTags($input, $allowed?) : string
StringUtils.StripComments($input) : string
StringUtils.HardWrap($input, $length?, $htmlTag?) : string
Variadic manipulation

Remove and Split are also variadic — they accept multiple arguments:

// Remove multiple substrings at once
StringUtils.Remove(path, "../", "./", "//");

// Split by multiple delimiters at once
StringUtils.Split(input, ",", ";", "|"); // Split on comma OR semicolon OR pipe

Format uses positional placeholders:

const message = StringUtils.Format("User {0} created {1} records", userName, count);
// → "User John created 42 records"

const path = StringUtils.Format("{0}/api/{1}/{2}", baseUrl, "products", productId);
// → "https://example.com/api/products/abc123"

Strip methods:

// Remove HTML/JS tags (optional allowed tags)
const clean = StringUtils.StripTags(htmlContent);
const partial = StringUtils.StripTags(htmlContent, "<b><i>"); // Keep bold and italic

// Remove backslashes
const unescaped = StringUtils.StripSlashes(escapedString);

// Remove comments (// and /* */ style)
const noComments = StringUtils.StripComments(sourceCode);

// Wrap long text to fixed-width lines
const wrapped = StringUtils.HardWrap(longText, 80); // HTML line breaks
const wrappedPlain = StringUtils.HardWrap(longText, 80, false); // Plain \n breaks

Case & Casing​

StringUtils.ToLowerCase($input : string) : string
StringUtils.ToUpperCase($input : string) : string
StringUtils.ToCamelCase($input : string) : string
StringUtils.ToCamelCase("my-component-name");  // → "MyComponentName"
StringUtils.ToCamelCase("some_snake_case"); // → "SomeSnakeCase"
note

ToLowerCase and ToUpperCase are null-safe wrappers. For known non-null strings, vanilla .toLowerCase() / .toUpperCase() is equally fine.

Character Access​

StringUtils.getCharacterAt($input, $index) : string   // Character at position
StringUtils.getCodeAt($input, $index) : number // Unicode code point (or null)
StringUtils.ToArray($input) : string[] // Split into character array
const firstChar = StringUtils.getCharacterAt(name, 0);
const charCode = StringUtils.getCodeAt(name, 0);
const chars = StringUtils.ToArray("Hello"); // → ["H", "e", "l", "l", "o"]

Type Conversion​

StringUtils.ToInteger($value : string) : number     // parseInt with base 10
StringUtils.ToDouble($value : string) : number // parseFloat
StringUtils.ToBoolean($value : string) : boolean // "true"/"1"/"yes" → true
StringUtils.ToHexadecimal($value : string) : number // Hex string to number (or null)

These methods handle edge cases that parseInt() and parseFloat() don't:

// Safe integer parsing
const page = StringUtils.ToInteger(queryParam); // Handles null, undefined, non-numeric

// Safe float parsing
const rate = StringUtils.ToDouble(inputValue);

// Boolean from string ("true", "1", "yes" → true)
const isActive = StringUtils.ToBoolean(configValue);

// Hex parsing
const color = StringUtils.ToHexadecimal("FF00AA");

Hashing​

StringUtils.getCrc($input : string) : number    // CRC32 checksum
StringUtils.getSha1($input : string) : string // Irreversible SHA1 hash
const checksum = StringUtils.getCrc(fileContent);
const hash = StringUtils.getSha1(password);

Version Comparison​

StringUtils.VersionIsLower($value : string, $pattern : string) : boolean

Compares version strings (e.g., "2.1.0" vs "2.2.0"). Returns true if $value is lower than $pattern:

StringUtils.VersionIsLower("1.9.0", "2.0.0");  // true
StringUtils.VersionIsLower("2.1.0", "2.0.0"); // false
StringUtils.VersionIsLower("2.0.0", "2.0.0"); // false

Year Range Helper​

StringUtils.YearFrom($start : number) : string

Returns a year range string from start year to current year. Used for copyright headers:

StringUtils.YearFrom(2020);  // → "2020 - 2026" (assuming current year is 2026)
StringUtils.YearFrom(2026); // → "2026" (same year — no range)

Output Helpers​

StringUtils.NewLine($htmlTag? : boolean) : string   // <br/> or \n
StringUtils.Space($count?, $htmlTag?) : string // &nbsp; or space
StringUtils.Tab($count?, $htmlTag?) : string // Tab characters

These return HTML entities by default, or plain text when $htmlTag is false:

const br = StringUtils.NewLine();        // → "<br/>"
const nl = StringUtils.NewLine(false); // → "\n"

const spaces = StringUtils.Space(4); // → "&nbsp;&nbsp;&nbsp;&nbsp;"
const plainSpaces = StringUtils.Space(4, false); // → " "

Complete Method Reference​

MethodDescription
IsEmpty($input)true if empty, null, or undefined
Length($input)String length or 0
Contains($input, ...$search)Variadic — true if any found
ContainsIgnoreCase($input, ...$search)Case-insensitive variadic contains
StartsWith($input, $search)Starts with prefix
EndsWith($input, $search)Ends with suffix
IndexOf($input, $search, $fromStart?, $offset?)Position of substring or -1
OccurrenceCount($input, $searchFor)Count of occurrences
PatternMatched($pattern, $value)Wildcard * pattern match
Replace($input, $search, $replacement)Replace all occurrences
Remove($input, ...$search)Variadic — remove substrings
Split($input, ...$splitBy)Variadic — split by multiple delimiters
Substring($input, $start, $end?)Extract substring
Format($template, ...$args)Positional {0} placeholder replacement
StripSlashes($input)Remove backslashes
StripTags($input, $allowed?)Remove HTML/JS tags
StripComments($input)Remove // and /* */ comments
HardWrap($input, $length?, $htmlTag?)Word-wrap to max line length
ToLowerCase($input)Null-safe lowercase
ToUpperCase($input)Null-safe uppercase
ToCamelCase($input)Convert to CamelCase
getCharacterAt($input, $index)Character at position
getCodeAt($input, $index)Unicode code point
ToArray($input)Split into character array
ToInteger($input)Safe parseInt (base 10)
ToDouble($input)Safe parseFloat
ToBoolean($input)String to boolean
ToHexadecimal($input)Hex string to number
getCrc($input)CRC32 checksum
getSha1($input)SHA1 hash
VersionIsLower($value, $pattern)Version string comparison
YearFrom($start)Year range string
NewLine($htmlTag?)Line break character
Space($count?, $htmlTag?)Space character(s)
Tab($count?, $htmlTag?)Tab character(s)

When to Use StringUtils vs Vanilla​

OperationStringUtilsVanillaRecommendation
Contains checkStringUtils.Contains()str.includes()StringUtils — null-safe, variadic. Native in hot paths (guard nullable)
Starts / ends withStringUtils.StartsWith()str.startsWith()Native in hot paths (guard nullable); StringUtils for nullable input elsewhere
ReplaceStringUtils.Replace()str.replace()StringUtils — null-safe
SplitStringUtils.Split()str.split()StringUtils — null-safe, multi-delimiter
Format stringStringUtils.Format()Template literalsStringUtils for dynamic templates, template literals for static
Parse integerStringUtils.ToInteger()parseInt()StringUtils — handles edge cases
CamelCaseStringUtils.ToCamelCase()Manual regexStringUtils — handles multiple formats
Regex match—str.match() / RegExpVanilla — StringUtils doesn't cover regex
Trim—str.trim()Vanilla — simple and reliable
toLowerCase/toUpperCaseStringUtils.ToLowerCase()str.toLowerCase()Vanilla for known strings; StringUtils for nullable
Template with variables—`Hello ${name}`Vanilla template literals — cleaner syntax
Wildcard matchingStringUtils.PatternMatched()Manual regexStringUtils — simpler API
Decision rule

Use StringUtils when the input might be null/undefined or comes from external sources. Use vanilla when you're confident the value is a valid string and the operation is straightforward (trim, case change, regex, template literals).


See also: Utilities Overview | ObjectValidator | JsonUtils | Convert