Find & Replace — TypeScript source
Find and replace text with literal or regular-expression matching, global replace, case sensitivity, whole-word, and capture-group substitution. Live match counter.
This is the TypeScript implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Pure find & replace - no React, no DOM, deterministic.
// Supports literal and regex matching, capture-group substitution, case
// sensitivity, whole-word, and global mode. Never throws.
export interface FindReplaceOptions {
isRegex: boolean; // default false
caseSensitive: boolean; // default true
wholeWord: boolean; // default false
global: boolean; // default true
multiline?: boolean; // regex mode only, default false
}
export interface FindReplaceResult {
result: string;
matches: number;
error: string | null;
}
export function escapeRegExp(s: string): string {
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
export const defaultOptions: FindReplaceOptions = {
isRegex: false,
caseSensitive: true,
wholeWord: false,
global: true,
multiline: false,
};
function buildRegex(find: string, opts: FindReplaceOptions): RegExp | { error: string } {
let pattern = opts.isRegex ? find : escapeRegExp(find);
if (opts.wholeWord) pattern = `\\b${pattern}\\b`;
let flags = opts.global ? 'g' : '';
if (!opts.caseSensitive) flags += 'i';
if (opts.isRegex && opts.multiline) flags += 'm';
try {
return new RegExp(pattern, flags);
} catch (e) {
return { error: (e as Error).message };
}
}
export function countMatches(
input: string,
find: string,
optsIn: Partial<FindReplaceOptions> = {},
): { matches: number; error: string | null } {
const opts: FindReplaceOptions = { ...defaultOptions, ...optsIn };
if (find === '') return { matches: 0, error: null };
const re = buildRegex(find, opts);
if (re instanceof RegExp) {
const m = input.match(re);
return { matches: m ? m.length : 0, error: null };
}
return { matches: 0, error: re.error };
}
export function findReplace(
input: string,
find: string,
replacement: string,
optsIn: Partial<FindReplaceOptions> = {},
): FindReplaceResult {
const opts: FindReplaceOptions = { ...defaultOptions, ...optsIn };
if (find === '') return { result: input, matches: 0, error: null };
const re = buildRegex(find, opts);
if (!(re instanceof RegExp)) {
return { result: input, matches: 0, error: re.error };
}
const matches = input.match(re)?.length ?? 0;
// Rebuild as a fresh regex (the counting match advanced lastIndex on /g).
const re2 = new RegExp(re.source, re.flags);
const result = input.replace(re2, replacement);
return { result, matches, error: null };
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →