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
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
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
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"
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 // 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); // → " "
const plainSpaces = StringUtils.Space(4, false); // → " "
Complete Method Reference
| Method | Description |
|---|---|
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
| Operation | StringUtils | Vanilla | Recommendation |
|---|---|---|---|
| Contains check | StringUtils.Contains() | str.includes() | StringUtils — null-safe, variadic. Native in hot paths (guard nullable) |
| Starts / ends with | StringUtils.StartsWith() | str.startsWith() | Native in hot paths (guard nullable); StringUtils for nullable input elsewhere |
| Replace | StringUtils.Replace() | str.replace() | StringUtils — null-safe |
| Split | StringUtils.Split() | str.split() | StringUtils — null-safe, multi-delimiter |
| Format string | StringUtils.Format() | Template literals | StringUtils for dynamic templates, template literals for static |
| Parse integer | StringUtils.ToInteger() | parseInt() | StringUtils — handles edge cases |
| CamelCase | StringUtils.ToCamelCase() | Manual regex | StringUtils — handles multiple formats |
| Regex match | — | str.match() / RegExp | Vanilla — StringUtils doesn't cover regex |
| Trim | — | str.trim() | Vanilla — simple and reliable |
| toLowerCase/toUpperCase | StringUtils.ToLowerCase() | str.toLowerCase() | Vanilla for known strings; StringUtils for nullable |
| Template with variables | — | `Hello ${name}` | Vanilla template literals — cleaner syntax |
| Wildcard matching | StringUtils.PatternMatched() | Manual regex | StringUtils — simpler API |
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