🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples de Traitement de Chaînes Web TypeScript
Exemples de traitement de chaînes Web TypeScript incluant la manipulation de chaînes, le correspondance de modèles et la transformation de texte
💻 Diviser et Joindre des Chaînes typescript
🟢 simple
⭐⭐
Diviser les chaînes en tableaux et joindre les tableaux en chaînes avec divers séparateurs et délimiteurs
⏱️ 25 min
🏷️ typescript, web, string processing
Prerequisites:
Basic TypeScript
// Web TypeScript String Split and Join Examples
// Splitting strings into arrays and joining arrays back into strings
// 1. Basic String Splitting
class StringSplitter {
// Split by single character
static splitByChar(text: string, delimiter: string): string[] {
return text.split(delimiter);
}
// Split by whitespace
static splitByWhitespace(text: string): string[] {
return text.split(/\s+/);
}
// Split into words (handles multiple spaces)
static splitIntoWords(text: string): string[] {
return text.trim().split(/\s+/).filter(word => word.length > 0);
}
// Split by line
static splitByLine(text: string): string[] {
return text.split(/\r?\n/);
}
// Split by length
static splitByLength(text: string, length: number): string[] {
const result: string[] = [];
for (let i = 0; i < text.length; i += length) {
result.push(text.slice(i, i + length));
}
return result;
}
// Split by multiple delimiters
static splitByMultiple(text: string, delimiters: string[]): string[] {
let result = text;
for (const delimiter of delimiters) {
result = result.split(delimiter).join(' ');
}
return result.split(/\s+/).filter(part => part.length > 0);
}
// Split keeping delimiters
static splitKeepingDelimiters(text: string, delimiter: string): string[] {
const parts: string[] = [];
let lastIndex = 0;
let index;
while ((index = text.indexOf(delimiter, lastIndex)) !== -1) {
parts.push(text.slice(lastIndex, index));
parts.push(delimiter);
lastIndex = index + delimiter.length;
}
parts.push(text.slice(lastIndex));
return parts;
}
// Split and trim
static splitAndTrim(text: string, delimiter: string): string[] {
return text.split(delimiter).map(part => part.trim()).filter(part => part.length > 0);
}
// Split into chunks of balanced parentheses
static splitBalanced(text: string, open: string, close: string): string[] {
const chunks: string[] = [];
let current = '';
let depth = 0;
for (const char of text) {
if (char === open) {
depth++;
current += char;
} else if (char === close) {
depth--;
current += char;
if (depth === 0 && current.length > 0) {
chunks.push(current);
current = '';
}
} else {
if (depth > 0) {
current += char;
}
}
}
if (current.length > 0) {
chunks.push(current);
}
return chunks;
}
}
// 2. Advanced String Joining
class StringJoiner {
// Join with separator
static join(parts: string[], separator: string): string {
return parts.join(separator);
}
// Join with new line
static joinWithNewLine(parts: string[]): string {
return parts.join('\n');
}
// Join with comma and space
static joinWithComma(parts: string[]): string {
return parts.join(', ');
}
// Join with custom prefix/suffix
static joinWithWrapper(parts: string[], separator: string, prefix: string, suffix: string): string {
return prefix + parts.join(separator) + suffix;
}
// Join with conditional separator
static joinConditional(parts: string[], separator: string): string {
return parts.filter(part => part !== null && part !== undefined && part.length > 0)
.join(separator);
}
// Join and limit
static joinWithLimit(parts: string[], separator: string, max: number, suffix: string = '...'): string {
if (parts.length <= max) {
return parts.join(separator);
}
return parts.slice(0, max).join(separator) + suffix;
}
// Join with last separator different
static joinWithOxfordComma(parts: string[]): string {
if (parts.length === 0) return '';
if (parts.length === 1) return parts[0];
if (parts.length === 2) return parts.join(' and ');
return parts.slice(0, -1).join(', ') + ', and ' + parts[parts.length - 1];
}
// Join with numbering
static joinWithNumbering(parts: string[], separator: string): string {
return parts.map((part, index) => `${index + 1}. ${part}`).join(separator);
}
}
// 3. String Tokenizer
class StringTokenizer {
private tokens: string[] = [];
private index: number = 0;
constructor(input: string, delimiters: string = ' \t\n\r') {
this.tokens = this.tokenize(input, delimiters);
}
private tokenize(input: string, delimiters: string): string[] {
const result: string[] = [];
let current = '';
for (const char of input) {
if (delimiters.includes(char)) {
if (current.length > 0) {
result.push(current);
current = '';
}
} else {
current += char;
}
}
if (current.length > 0) {
result.push(current);
}
return result;
}
hasMoreTokens(): boolean {
return this.index < this.tokens.length;
}
nextToken(): string | null {
if (this.hasMoreTokens()) {
return this.tokens[this.index++];
}
return null;
}
countTokens(): number {
return this.tokens.length - this.index;
}
getAllTokens(): string[] {
return [...this.tokens];
}
reset(): void {
this.index = 0;
}
}
// 4. String Builder
class StringBuilder {
private parts: string[] = [];
// Append string
append(text: string): this {
this.parts.push(text);
return this;
}
// Append line
appendLine(text: string): this {
this.parts.push(text);
this.parts.push('\n');
return this;
}
// Append multiple strings
appendAll(...texts: string[]): this {
this.parts.push(...texts);
return this;
}
// Clear builder
clear(): this {
this.parts = [];
return this;
}
// Get length
get length(): number {
return this.parts.join('').length;
}
// Check if empty
isEmpty(): boolean {
return this.parts.length === 0 || this.parts.every(p => p.length === 0);
}
// Build final string
toString(): string {
return this.parts.join('');
}
// Build with separator
join(separator: string): string {
return this.parts.join(separator);
}
}
// 5. Template Engine (Basic)
class TemplateEngine {
// Simple variable substitution
static render(template: string, data: Record<string, any>): string {
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
return data[key] !== undefined ? String(data[key]) : match;
});
}
// Template with conditionals
static renderWithConditionals(
template: string,
data: Record<string, any>
): string {
let result = template;
// Handle {{#if var}}...{{/if}}
result = result.replace(/\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (match, varName, content) => {
return data[varName] ? content : '';
});
// Handle {{#unless var}}...{{/unless}}
result = result.replace(/\{\{#unless\s+(\w+)\}\}([\s\S]*?)\{\{\/unless\}\}/g, (match, varName, content) => {
return !data[varName] ? content : '';
});
// Replace variables
return this.render(result, data);
}
// Template with loops
static renderWithLoops(
template: string,
data: Record<string, any>
): string {
let result = template;
// Handle {{#each items}}...{{/each}}
result = result.replace(
/\{\{#each\s+(\w+)\}\}([\s\S]*?)\{\{\/each\}\}/g,
(match, varName, itemTemplate) => {
const items = data[varName] as any[];
if (!Array.isArray(items)) return '';
return items.map((item, index) => {
let rendered = itemTemplate;
// Replace {{this}} with current item
rendered = rendered.replace(/\{\{this\}\}/g, String(item));
// Replace {{@index}} with current index
rendered = rendered.replace(/\{\{@index\}\}/g, String(index));
return rendered;
}).join('');
}
);
return this.render(result, data);
}
}
// 6. Text Formatter
class TextFormatter {
// Capitalize first letter
static capitalize(text: string): string {
if (text.length === 0) return text;
return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
}
// Capitalize each word
static capitalizeWords(text: string): string {
return text.split(/\s+/).map(word => this.capitalize(word)).join(' ');
}
// Convert to title case
static toTitleCase(text: string): string {
const minorWords = ['a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by'];
return text.split(/\s+/).map((word, index) => {
const lowerWord = word.toLowerCase();
if (index === 0 || !minorWords.includes(lowerWord)) {
return this.capitalize(lowerWord);
}
return lowerWord;
}).join(' ');
}
// Convert to camel case
static toCamelCase(text: string): string {
return text.split(/[_\s-]+/)
.map((word, index) => {
if (index === 0) {
return word.toLowerCase();
}
return this.capitalize(word.toLowerCase());
})
.join('');
}
// Convert to snake case
static toSnakeCase(text: string): string {
return text.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');
}
// Convert to kebab case
static toKebabCase(text: string): string {
return text.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '');
}
// Truncate text
static truncate(text: string, maxLength: number, suffix: string = '...'): string {
if (text.length <= maxLength) {
return text;
}
return text.slice(0, maxLength - suffix.length) + suffix;
}
// Truncate words
static truncateWords(text: string, maxWords: number, suffix: string = '...'): string {
const words = text.split(/\s+/);
if (words.length <= maxWords) {
return text;
}
return words.slice(0, maxWords).join(' ') + suffix;
}
// Reverse string
static reverse(text: string): string {
return text.split('').reverse().join('');
}
// Shuffle words
static shuffleWords(text: string): string {
const words = text.split(/\s+/);
const shuffled = [...words].sort(() => Math.random() - 0.5);
return shuffled.join(' ');
}
// Justify text (add spaces to make each line the same width)
static justify(text: string, lineWidth: number): string {
const words = text.split(/\s+/);
const lines: string[] = [];
let currentLine: string[] = [];
let currentLength = 0;
for (const word of words) {
if (currentLength + word.length + currentLine.length > lineWidth) {
lines.push(currentLine.join(' '));
currentLine = [];
currentLength = 0;
}
currentLine.push(word);
currentLength += word.length;
}
if (currentLine.length > 0) {
lines.push(currentLine.join(' '));
}
return lines.join('\n');
}
}
// 7. String Encoding/Decoding
class StringEncoder {
// Base64 encode
static toBase64(text: string): string {
return btoa(unescape(encodeURIComponent(text)));
}
// Base64 decode
static fromBase64(base64: string): string {
return decodeURIComponent(escape(atob(base64)));
}
// URL encode
static encodeURL(text: string): string {
return encodeURIComponent(text);
}
// URL decode
static decodeURL(text: string): string {
return decodeURIComponent(text);
}
// HTML encode
static encodeHTML(text: string): string {
const htmlEntities: Record<string, string> = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, char => htmlEntities[char]);
}
// HTML decode
static decodeHTML(text: string): string {
const htmlEntities: Record<string, string> = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
''': "'"
};
return text.replace(/&|<|>|"|'/g, entity => htmlEntities[entity]);
}
}
// 8. String Analyzer
class StringAnalyzer {
// Count characters
static countCharacters(text: string, includeSpaces: boolean = true): number {
if (includeSpaces) {
return text.length;
}
return text.replace(/\s/g, '').length;
}
// Count words
static countWords(text: string): number {
return text.trim().split(/\s+/).filter(word => word.length > 0).length;
}
// Count lines
static countLines(text: string): number {
return text.split(/\r?\n/).length;
}
// Count paragraphs
static countParagraphs(text: string): number {
return text.split(/\n\s*\n/).filter(para => para.trim().length > 0).length;
}
// Get character frequency
static characterFrequency(text: string, caseSensitive: boolean = false): Map<string, number> {
const processed = caseSensitive ? text : text.toLowerCase();
const freq = new Map<string, number>();
for (const char of processed) {
if (char.match(/\w/)) {
freq.set(char, (freq.get(char) || 0) + 1);
}
}
return freq;
}
// Get word frequency
static wordFrequency(text: string): Map<string, number> {
const words = text.toLowerCase().split(/\s+/);
const freq = new Map<string, number>();
for (const word of words) {
if (word.match(/\w+/)) {
freq.set(word, (freq.get(word) || 0) + 1);
}
}
return freq;
}
// Find longest word
static findLongestWord(text: string): string {
const words = text.split(/\s+/);
return words.reduce((longest, word) => word.length > longest.length ? word : longest, '');
}
// Find shortest word
static findShortestWord(text: string): string {
const words = text.split(/\s+/).filter(w => w.length > 0);
return words.reduce((shortest, word) => word.length < shortest.length ? word : shortest, words[0] || '');
}
// Average word length
static averageWordLength(text: string): number {
const words = text.split(/\s+/).filter(w => w.length > 0);
if (words.length === 0) return 0;
const totalLength = words.reduce((sum, word) => sum + word.length, 0);
return totalLength / words.length;
}
}
// Usage Examples
async function demonstrateStringSplitJoin() {
console.log('=== Web TypeScript String Split and Join Examples ===\n');
// 1. Basic splitting
console.log('--- 1. Basic Splitting ---');
const text = 'Hello World TypeScript Programming';
console.log(`Split by space: ${StringSplitter.splitByChar(text, ' ')}`);
console.log(`Split into words: ${StringSplitter.splitIntoWords(text)}`);
console.log(`Split by length (5): ${StringSplitter.splitByLength(text, 5)}`);
const multiline = 'Line 1\nLine 2\nLine 3';
console.log(`Split by line: ${StringSplitter.splitByLine(multiline)}`);
// 2. Advanced splitting
console.log('\n--- 2. Advanced Splitting ---');
const complex = 'one,two;three:four';
console.log(`Split by multiple: ${StringSplitter.splitByMultiple(complex, [',', ';', ':'])}`);
const csv = 'apple, banana, cherry, date';
console.log(`Split and trim: ${StringSplitter.splitAndTrim(csv, ',')}`);
// 3. Joining
console.log('\n--- 3. Joining ---');
const fruits = ['apple', 'banana', 'cherry'];
console.log(`Join with comma: ${StringJoiner.joinWithComma(fruits)}`);
console.log(`Join with comma and space: ${StringJoiner.join(fruits, ', ')}`);
console.log(`Join with new line: ${StringJoiner.joinWithNewLine(fruits)}`);
console.log(`Oxford comma: ${StringJoiner.joinWithOxfordComma(fruits)}`);
// 4. String builder
console.log('\n--- 4. String Builder ---');
const builder = new StringBuilder();
builder.append('Hello').append(' ').append('World').appendLine('!');
builder.append('This is TypeScript');
console.log(`Built string: ${builder.toString()}`);
console.log(`Length: ${builder.length}`);
// 5. Tokenizer
console.log('\n--- 5. Tokenizer ---');
const tokenizer = new StringTokenizer('This is a test string', ' ');
console.log('Tokens:');
while (tokenizer.hasMoreTokens()) {
console.log(` ${tokenizer.nextToken()}`);
}
// 6. Template engine
console.log('\n--- 6. Template Engine ---');
const template = 'Hello {{name}}, welcome to {{place}}!';
const data = { name: 'Alice', place: 'Wonderland' };
console.log(`Rendered: ${TemplateEngine.render(template, data)}`);
// 7. Text formatting
console.log('\n--- 7. Text Formatting ---');
console.log(`Capitalize: ${TextFormatter.capitalize('hello world')}`);
console.log(`Title case: ${TextFormatter.toTitleCase('the quick brown fox')}`);
console.log(`Camel case: ${TextFormatter.toCamelCase('hello_world_text')}`);
console.log(`Snake case: ${TextFormatter.toSnakeCase('helloWorldText')}`);
console.log(`Kebab case: ${TextFormatter.toKebabCase('helloWorldText')}`);
// 8. Encoding/Decoding
console.log('\n--- 8. Encoding/Decoding ---');
const original = 'Hello World!';
const encoded = StringEncoder.toBase64(original);
const decoded = StringEncoder.fromBase64(encoded);
console.log(`Original: ${original}`);
console.log(`Base64: ${encoded}`);
console.log(`Decoded: ${decoded}`);
// 9. String analyzer
console.log('\n--- 9. String Analyzer ---');
const longText = 'The quick brown fox jumps over the lazy dog. The dog was not amused!';
console.log(`Characters: ${StringAnalyzer.countCharacters(longText)}`);
console.log(`Characters (no spaces): ${StringAnalyzer.countCharacters(longText, false)}`);
console.log(`Words: ${StringAnalyzer.countWords(longText)}`);
console.log(`Lines: ${StringAnalyzer.countLines(longText)}`);
console.log(`Longest word: ${StringAnalyzer.findLongestWord(longText)}`);
console.log(`Shortest word: ${StringAnalyzer.findShortestWord(longText)}`);
console.log(`Average word length: ${StringAnalyzer.averageWordLength(longText).toFixed(2)}`);
console.log('\n=== All String Split and Join Examples Completed ===');
}
// Export classes
export { StringSplitter, StringJoiner, StringTokenizer, StringBuilder, TemplateEngine, TextFormatter, StringEncoder, StringAnalyzer };
export { demonstrateStringSplitJoin };
💻 Remplacement de Chaînes typescript
🟢 simple
⭐⭐⭐
Remplacer, substituer et transformer des chaînes en utilisant diverses méthodes et stratégies
⏱️ 25 min
🏷️ typescript, web, string processing, replace
Prerequisites:
Basic TypeScript
// Web TypeScript String Replace Examples
// Comprehensive string replacement and transformation techniques
// 1. Basic String Replacement
class StringReplacer {
// Replace first occurrence
static replaceFirst(text: string, search: string, replacement: string): string {
return text.replace(search, replacement);
}
// Replace all occurrences
static replaceAll(text: string, search: string, replacement: string): string {
return text.split(search).join(replacement);
}
// Replace all (case insensitive)
static replaceAllIgnoreCase(text: string, search: string, replacement: string): string {
const regex = new RegExp(search, 'gi');
return text.replace(regex, replacement);
}
// Replace at index
static replaceAt(text: string, index: number, length: number, replacement: string): string {
return text.slice(0, index) + replacement + text.slice(index + length);
}
// Replace between indices
static replaceBetween(text: string, start: number, end: number, replacement: string): string {
return text.slice(0, start) + replacement + text.slice(end);
}
}
// 2. Advanced String Replacement
class AdvancedReplacer {
// Replace using callback function
static replaceWithFunction(
text: string,
pattern: string | RegExp,
callback: (match: string, ...groups: string[]) => string
): string {
return text.replace(pattern, callback);
}
// Replace multiple values at once
static replaceMultiple(
text: string,
replacements: Record<string, string>
): string {
let result = text;
for (const [search, replacement] of Object.entries(replacements)) {
result = result.split(search).join(replacement);
}
return result;
}
// Replace with template
static replaceWithTemplate(
text: string,
pattern: string | RegExp,
template: string
): string {
return text.replace(pattern, template);
}
// Replace preserving case
static replacePreservingCase(text: string, search: string, replacement: string): string {
return text.replace(new RegExp(search, 'gi'), (match) => {
if (match === match.toUpperCase()) {
return replacement.toUpperCase();
} else if (match === match.toLowerCase()) {
return replacement.toLowerCase();
} else if (match[0] === match[0].toUpperCase()) {
return replacement.charAt(0).toUpperCase() + replacement.slice(1).toLowerCase();
}
return replacement;
});
}
// Replace nth occurrence
static replaceNth(
text: string,
search: string,
replacement: string,
n: number
): string {
const parts = text.split(search);
if (n < 0 || n >= parts.length - 1) {
return text;
}
parts[n] = replacement;
return parts.join(search);
}
// Replace first and last
static replaceFirstAndLast(
text: string,
search: string,
replacement: string
): string {
const parts = text.split(search);
if (parts.length <= 1) {
return text;
}
parts[0] = replacement;
parts[parts.length - 1] = replacement;
return parts.join(search);
}
}
// 3. Pattern-Based Replacement
class PatternReplacer {
// Replace using regex
static replaceWithRegex(
text: string,
pattern: RegExp,
replacement: string
): string {
return text.replace(pattern, replacement);
}
// Replace words
static replaceWords(
text: string,
words: string[],
replacement: string
): string {
const pattern = new RegExp(`\\b(${words.join('|')})\\b`, 'gi');
return text.replace(pattern, replacement);
}
// Replace vowels
static replaceVowels(text: string, replacement: string): string {
return text.replace(/[aeiou]/gi, replacement);
}
// Replace consonants
static replaceConsonants(text: string, replacement: string): string {
return text.replace(/[^aeiou\s]/gi, replacement);
}
// Replace digits
static replaceDigits(text: string, replacement: string): string {
return text.replace(/\d/g, replacement);
}
// Replace whitespace
static replaceWhitespace(text: string, replacement: string): string {
return text.replace(/\s+/g, replacement);
}
// Replace line breaks
static replaceLineBreaks(text: string, replacement: string): string {
return text.replace(/\r?\n/g, replacement);
}
}
// 4. Text Transformation
class TextTransformer {
// To uppercase
static toUpperCase(text: string): string {
return text.toUpperCase();
}
// To lowercase
static toLowerCase(text: string): string {
return text.toLowerCase();
}
// To title case
static toTitleCase(text: string): string {
return text.replace(/\w\S*/g, (word) => {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
});
}
// To sentence case
static toSentenceCase(text: string): string {
return text.toLowerCase().replace(/(\.\s*)([a-z])/g, (_, prefix, letter) => {
return prefix + letter.toUpperCase();
});
}
// To alternating case
static toAlternatingCase(text: string): string {
return text.split('').map((char, index) => {
return index % 2 === 0 ? char.toUpperCase() : char.toLowerCase();
}).join('');
}
// To inverse case
static toInverseCase(text: string): string {
return text.split('').map(char => {
return char === char.toUpperCase() ? char.toLowerCase() : char.toUpperCase();
}).join('');
}
// Capitalize first letter
static capitalize(text: string): string {
return text.charAt(0).toUpperCase() + text.slice(1);
}
// Capitalize all words
static capitalizeWords(text: string): string {
return text.replace(/\b\w/g, char => char.toUpperCase());
}
}
// 5. String Template Replacement
class TemplateReplacer {
// Replace {{variable}} placeholders
static replaceVariables(
template: string,
variables: Record<string, any>
): string {
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
return variables[key] !== undefined ? String(variables[key]) : match;
});
}
// Replace ${variable} placeholders
static replaceES6Variables(
template: string,
variables: Record<string, any>
): string {
return template.replace(/\$\{(\w+)\}/g, (match, key) => {
return variables[key] !== undefined ? String(variables[key]) : match;
});
}
// Replace %s placeholders (printf style)
static replacePrintfStyle(template: string, ...values: any[]): string {
let index = 0;
return template.replace(/%s/g, () => {
return index < values.length ? String(values[index++]) : '%s';
});
}
// Replace ? placeholders (SQL style)
static replaceQuestionMarks(template: string, ...values: any[]): string {
let index = 0;
return template.replace(/\?/g, () => {
return index < values.length ? String(values[index++]) : '?';
});
}
// Replace with numbered placeholders {0}, {1}, etc.
static replaceNumbered(template: string, ...values: any[]): string {
return template.replace(/\{(\d+)\}/g, (match, index) => {
const i = parseInt(index);
return i < values.length ? String(values[i]) : match;
});
}
}
// 6. Masking and Censoring
class StringMasker {
// Mask email
static maskEmail(email: string): string {
const [username, domain] = email.split('@');
if (username.length <= 2) {
return `${username[0]}***@${domain}`;
}
return `${username[0]}${'*'.repeat(username.length - 2)}${username[username.length - 1]}@${domain}`;
}
// Mask phone number
static maskPhone(phone: string): string {
const cleaned = phone.replace(/\D/g, '');
if (cleaned.length < 4) {
return '*'.repeat(cleaned.length);
}
return cleaned.slice(0, -4).replace(/\d/g, '*') + cleaned.slice(-4);
}
// Mask credit card
static maskCreditCard(card: string): string {
const cleaned = card.replace(/\s/g, '');
if (cleaned.length < 4) {
return cleaned;
}
return '*'.repeat(cleaned.length - 4) + cleaned.slice(-4);
}
// Mask string partially
static maskPartial(text: string, visibleStart: number = 2, visibleEnd: number = 2): string {
if (text.length <= visibleStart + visibleEnd) {
return text;
}
return text.slice(0, visibleStart) +
'*'.repeat(text.length - visibleStart - visibleEnd) +
text.slice(-visibleEnd);
}
// Censor words
static censorWords(text: string, words: string[], censorChar: string = '*'): string {
const pattern = new RegExp(`\\b(${words.join('|')})\\b`, 'gi');
return text.replace(pattern, (match) => {
return censorChar.repeat(match.length);
});
}
// Censor profanity
static censorProfanity(text: string, censorChar: string = '*'): string {
const profanityList = ['damn', 'hell', 'shit', 'fuck']; // Add more as needed
return this.censorWords(text, profanityList, censorChar);
}
}
// 7. String Cleanup
class StringCleaner {
// Trim whitespace
static trim(text: string): string {
return text.trim();
}
// Trim left
static trimLeft(text: string): string {
return text.trimLeft();
}
// Trim right
static trimRight(text: string): string {
return text.trimRight();
}
// Remove extra spaces
static collapseWhitespace(text: string): string {
return text.replace(/\s+/g, ' ').trim();
}
// Remove all whitespace
static removeAllWhitespace(text: string): string {
return text.replace(/\s/g, '');
}
// Remove line breaks
static removeLineBreaks(text: string): string {
return text.replace(/\r?\n/g, ' ');
}
// Remove punctuation
static removePunctuation(text: string): string {
return text.replace(/[.,\/#!$%^&*;:{}=\-_`~()]/g, '');
}
// Remove special characters
static removeSpecialChars(text: string): string {
return text.replace(/[^a-zA-Z0-9\s]/g, '');
}
// Remove duplicate characters
static removeDuplicateChars(text: string): string {
return text.split('').filter((char, index, self) => {
return self.indexOf(char) === index;
}).join('');
}
// Remove duplicate words
static removeDuplicateWords(text: string): string {
return text.replace(/\b(\w+)\b(\s+\1\b)+/gi, '$1');
}
}
// 8. String Normalization
class StringNormalizer {
// Normalize whitespace
static normalizeWhitespace(text: string): string {
return text.replace(/\s+/g, ' ').trim();
}
// Normalize line endings
static normalizeLineEndings(text: string, lineEnding: '\n' | '\r\n' = '\n'): string {
return text.replace(/\r?\n/g, lineEnding);
}
// Normalize case to lowercase
static normalizeToLower(text: string): string {
return text.toLowerCase();
}
// Normalize case to uppercase
static normalizeToUpper(text: string): string {
return text.toUpperCase();
}
// Normalize quotes
static normalizeQuotes(text: string): string {
return text
.replace(/[\u2018\u2019]/g, "'")
.replace(/[\u201C\u201D]/g, '"');
}
// Normalize dashes
static normalizeDashes(text: string): string {
return text.replace(/[\u2010-\u2015\u2212]/g, '-');
}
// Normalize accented characters
static normalizeAccents(text: string): string {
return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
}
// Usage Examples
async function demonstrateStringReplace() {
console.log('=== Web TypeScript String Replace Examples ===\n');
// 1. Basic replacement
console.log('--- 1. Basic Replacement ---');
const text = 'Hello World! World is beautiful.';
console.log(`Original: ${text}`);
console.log(`Replace first 'World': ${StringReplacer.replaceFirst(text, 'World', 'Earth')}`);
console.log(`Replace all 'World': ${StringReplacer.replaceAll(text, 'World', 'Earth')}`);
console.log(`Replace all case insensitive: ${StringReplacer.replaceAllIgnoreCase(text, 'world', 'Earth')}`);
// 2. Advanced replacement
console.log('\n--- 2. Advanced Replacement ---');
const multiText = 'The quick brown fox jumps over the lazy dog.';
console.log(`Original: ${multiText}`);
const replaced = AdvancedReplacer.replaceMultiple(multiText, {
'quick': 'slow',
'brown': 'white',
'lazy': 'energetic'
});
console.log(`Replace multiple: ${replaced}`);
console.log(`Replace 2nd 'the': ${AdvancedReplacer.replaceNth(multiText.toLowerCase(), 'the', 'a', 2)}`);
console.log(`Replace preserving case: ${AdvancedReplacer.replacePreservingCase(multiText, 'the', 'a')}`);
// 3. Pattern-based replacement
console.log('\n--- 3. Pattern-Based Replacement ---');
const patternText = 'Hello 123 World 456 Test 789';
console.log(`Original: ${patternText}`);
console.log(`Replace digits: ${PatternReplacer.replaceDigits(patternText, '#')}`);
console.log(`Replace words: ${PatternReplacer.replaceWords(patternText, ['Hello', 'World'], 'Hi')}`);
console.log(`Replace whitespace: ${PatternReplacer.replaceWhitespace(patternText, '-')}`);
// 4. Text transformation
console.log('\n--- 4. Text Transformation ---');
const transformText = 'hello world this is typescript';
console.log(`Original: ${transformText}`);
console.log(`Uppercase: ${TextTransformer.toUpperCase(transformText)}`);
console.log(`Lowercase: ${TextTransformer.toLowerCase(transformText)}`);
console.log(`Title case: ${TextTransformer.toTitleCase(transformText)}`);
console.log(`Sentence case: ${TextTransformer.toSentenceCase(transformText)}`);
console.log(`Alternating case: ${TextTransformer.toAlternatingCase('hello')}`);
console.log(`Inverse case: ${TextTransformer.toInverseCase('HeLLo WoRLd')}`);
// 5. Template replacement
console.log('\n--- 5. Template Replacement ---');
const template = 'Hello {{name}}, welcome to {{place}}! You have {{count}} messages.';
const variables = { name: 'Alice', place: 'Wonderland', count: 5 };
console.log(`Template: ${template}`);
console.log(`Replaced: ${TemplateReplacer.replaceVariables(template, variables)}`);
const printfTemplate = 'Hello %s, you are %s years old.';
console.log(`Printf style: ${TemplateReplacer.replacePrintfStyle(printfTemplate, 'Bob', 30)}`);
const numberedTemplate = 'Dear {0}, your order {1} is {2}.';
console.log(`Numbered: ${TemplateReplacer.replaceNumbered(numberedTemplate, 'John', '12345', 'ready')}`);
// 6. Masking
console.log('\n--- 6. Masking ---');
console.log(`Mask email: ${StringMasker.maskEmail('[email protected]')}`);
console.log(`Mask phone: ${StringMasker.maskPhone('(555) 123-4567')}`);
console.log(`Mask credit card: ${StringMasker.maskCreditCard('4532 1234 5678 9010')}`);
console.log(`Mask partial: ${StringMasker.maskPartial('SecretPassword', 2, 2)}`);
const censorText = 'This damn hell is really shitty';
console.log(`Censor: ${StringMasker.censorProfanity(censorText)}`);
// 7. Cleanup
console.log('\n--- 7. Cleanup ---');
const messy = ' This is a messy text \n with extra spaces ';
console.log(`Original: '${messy}'`);
console.log(`Trim: '${StringCleaner.trim(messy)}'`);
console.log(`Collapse whitespace: '${StringCleaner.collapseWhitespace(messy)}'`);
console.log(`Remove all whitespace: '${StringCleaner.removeAllWhitespace(messy)}'`);
console.log(`Remove line breaks: '${StringCleaner.removeLineBreaks(messy)}'`);
// 8. Normalization
console.log('\n--- 8. Normalization ---');
const unnormalized = 'Hello World!\n\rThis is a test.\n';
console.log(`Original: '${unnormalized}'`);
console.log(`Normalized whitespace: '${StringNormalizer.normalizeWhitespace(unnormalized)}'`);
console.log(`Normalized line endings: '${StringNormalizer.normalizeLineEndings(unnormalized)}'`);
const quotes = 'Hello "world" and 'goodbye'';
console.log(`Normalize quotes: ${StringNormalizer.normalizeQuotes(quotes)}`);
const accented = 'café résumé';
console.log(`Normalize accents: ${StringNormalizer.normalizeAccents(accented)}`);
console.log('\n=== All String Replace Examples Completed ===');
}
// Export classes
export { StringReplacer, AdvancedReplacer, PatternReplacer, TextTransformer, TemplateReplacer, StringMasker, StringCleaner, StringNormalizer };
export { demonstrateStringReplace };
💻 Expressions Régulières typescript
🟡 intermediate
⭐⭐⭐
Utiliser des expressions régulières pour la correspondance de modèles, la validation, la recherche et le remplacement de texte
⏱️ 30 min
🏷️ typescript, web, string processing, regex
Prerequisites:
Intermediate TypeScript, Regular Expressions
// Web TypeScript Regular Expressions Examples
// Pattern matching, validation, searching, and text replacement with regex
// 1. Pattern Matching
class PatternMatcher {
// Check if pattern matches
static test(text: string, pattern: string): boolean {
const regex = new RegExp(pattern);
return regex.test(text);
}
// Find all matches
static findAll(text: string, pattern: string, flags: string = 'g'): RegExpMatchArray | null {
const regex = new RegExp(pattern, flags);
return text.match(regex);
}
// Find first match
static findFirst(text: string, pattern: string): RegExpExecArray | null {
const regex = new RegExp(pattern);
return regex.exec(text);
}
// Extract groups from match
static extractGroups(text: string, pattern: string): Record<string, string> | null {
const regex = new RegExp(pattern);
const match = regex.exec(text);
if (!match) return null;
const groups: Record<string, string> = {};
if (match.groups) {
for (const [key, value] of Object.entries(match.groups)) {
groups[key] = value;
}
}
return groups;
}
// Match all with capturing groups
static matchWithGroups(text: string, pattern: string): Array<Record<string, string>> {
const regex = new RegExp(pattern, 'g');
const results: Array<Record<string, string>> = [];
let match;
while ((match = regex.exec(text)) !== null) {
const groups: Record<string, string> = {};
if (match.groups) {
for (const [key, value] of Object.entries(match.groups)) {
groups[key] = value;
}
}
results.push(groups);
}
return results;
}
// Check if string matches pattern entirely
static matchesEntirely(text: string, pattern: string): boolean {
const regex = new RegExp(`^${pattern}$`);
return regex.test(text);
}
}
// 2. Common Validators
class Validators {
// Email validation
static isValidEmail(email: string): boolean {
const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
return pattern.test(email);
}
// URL validation
static isValidURL(url: string): boolean {
const pattern = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?$/;
return pattern.test(url);
}
// Phone number validation (US format)
static isValidPhone(phone: string): boolean {
const pattern = /^\+?(\d{1,3})?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/;
return pattern.test(phone);
}
// IP address validation (IPv4)
static isValidIPv4(ip: string): boolean {
const pattern = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
return pattern.test(ip);
}
// Date validation (YYYY-MM-DD)
static isValidDate(date: string): boolean {
const pattern = /^(\d{4})-(\d{2})-(\d{2})$/;
if (!pattern.test(date)) return false;
const [, year, month, day] = date.match(pattern)!;
const dateObj = new Date(`${year}-${month}-${day}`);
return dateObj.getFullYear() === parseInt(year) &&
dateObj.getMonth() === parseInt(month) - 1 &&
dateObj.getDate() === parseInt(day);
}
// Credit card validation (Luhn algorithm)
static isValidCreditCard(cardNumber: string): boolean {
const cleaned = cardNumber.replace(/\s+/g, '');
if (!/^\d{13,19}$/.test(cleaned)) return false;
let sum = 0;
let isEven = false;
for (let i = cleaned.length - 1; i >= 0; i--) {
let digit = parseInt(cleaned[i]);
if (isEven) {
digit *= 2;
if (digit > 9) {
digit -= 9;
}
}
sum += digit;
isEven = !isEven;
}
return sum % 10 === 0;
}
// Username validation
static isValidUsername(username: string): boolean {
const pattern = /^[a-zA-Z0-9_]{3,16}$/;
return pattern.test(username);
}
// Password strength validation
static getPasswordStrength(password: string): 'weak' | 'medium' | 'strong' {
if (password.length < 8) return 'weak';
let score = 0;
if (/[a-z]/.test(password)) score++;
if (/[A-Z]/.test(password)) score++;
if (/[0-9]/.test(password)) score++;
if (/[^a-zA-Z0-9]/.test(password)) score++;
if (score <= 2) return 'weak';
if (score === 3) return 'medium';
return 'strong';
}
// Hex color validation
static isValidHexColor(color: string): boolean {
const pattern = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/;
return pattern.test(color);
}
}
// 3. Text Search with Regex
class RegexSearcher {
// Find all occurrences of pattern
static findAll(text: string, pattern: string): { match: string; index: number }[] {
const regex = new RegExp(pattern, 'gi');
const results: { match: string; index: number }[] = [];
let match;
while ((match = regex.exec(text)) !== null) {
results.push({
match: match[0],
index: match.index
});
}
return results;
}
// Find words matching pattern
static findWords(text: string, pattern: string): string[] {
const regex = new RegExp(`\\b${pattern}\\b`, 'gi');
const matches = text.match(regex);
return matches ? Array.from(new Set(matches.map(m => m.toLowerCase()))) : [];
}
// Find sentences containing pattern
static findSentences(text: string, pattern: string): string[] {
const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 0);
const regex = new RegExp(pattern, 'gi');
return sentences.filter(sentence => regex.test(sentence));
}
// Context search (find pattern with surrounding text)
static findWithContext(text: string, pattern: string, contextChars: number = 20): Array<{
match: string;
context: string;
index: number;
}> {
const regex = new RegExp(pattern, 'gi');
const results: Array<{ match: string; context: string; index: number }> = [];
let match;
while ((match = regex.exec(text)) !== null) {
const start = Math.max(0, match.index - contextChars);
const end = Math.min(text.length, match.index + match[0].length + contextChars);
results.push({
match: match[0],
context: text.slice(start, end),
index: match.index
});
}
return results;
}
}
// 4. Text Replacement with Regex
class RegexReplacer {
// Replace all occurrences
static replaceAll(text: string, pattern: string, replacement: string): string {
const regex = new RegExp(pattern, 'g');
return text.replace(regex, replacement);
}
// Replace with function
static replaceWithFunction(
text: string,
pattern: string,
replacer: (match: string, ...groups: string[]) => string
): string {
const regex = new RegExp(pattern, 'g');
return text.replace(regex, replacer);
}
// Replace but preserve case
static replacePreservingCase(text: string, pattern: string, replacement: string): string {
return text.replace(new RegExp(pattern, 'gi'), (match) => {
if (match === match.toUpperCase()) {
return replacement.toUpperCase();
} else if (match === match.toLowerCase()) {
return replacement.toLowerCase();
} else if (match[0] === match[0].toUpperCase()) {
return replacement.charAt(0).toUpperCase() + replacement.slice(1).toLowerCase();
}
return replacement;
});
}
// Remove all matches
static removeAll(text: string, pattern: string): string {
const regex = new RegExp(pattern, 'g');
return text.replace(regex, '');
}
// Remove duplicate words
static removeDuplicateWords(text: string): string {
return text.replace(/\b(\w+)\b(\s+\1\b)+/gi, '$1');
}
// Remove extra whitespace
static normalizeWhitespace(text: string): string {
return text.replace(/\s+/g, ' ').trim();
}
}
// 5. Text Extraction
class TextExtractor {
// Extract email addresses
static extractEmails(text: string): string[] {
const pattern = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
const matches = text.match(pattern);
return matches ? Array.from(new Set(matches)) : [];
}
// Extract URLs
static extractURLs(text: string): string[] {
const pattern = /https?:\/\/[^\s<>"{}|\\^\[\]]+/g;
const matches = text.match(pattern);
return matches ? Array.from(new Set(matches)) : [];
}
// Extract hashtags
static extractHashtags(text: string): string[] {
const pattern = /#\w+/g;
const matches = text.match(pattern);
return matches || [];
}
// Extract mentions
static extractMentions(text: string): string[] {
const pattern = /@\w+/g;
const matches = text.match(pattern);
return matches || [];
}
// Extract numbers
static extractNumbers(text: string): number[] {
const pattern = /-?\d+(\.\d+)?/g;
const matches = text.match(pattern);
return matches ? matches.map(m => parseFloat(m)) : [];
}
// Extract dates (YYYY-MM-DD format)
static extractDates(text: string): string[] {
const pattern = /\d{4}-\d{2}-\d{2}/g;
const matches = text.match(pattern);
return matches || [];
}
// Extract phone numbers
static extractPhones(text: string): string[] {
const pattern = /\+?\d{1,3}?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}/g;
const matches = text.match(pattern);
return matches || [];
}
}
// 6. Text Sanitization
class TextSanitizer {
// Remove HTML tags
static stripHTMLTags(text: string): string {
return text.replace(/<[^>]*>/g, '');
}
// Escape HTML
static escapeHTML(text: string): string {
const htmlEntities: Record<string, string> = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, char => htmlEntities[char]);
}
// Remove special characters
static removeSpecialChars(text: string, keepSpaces: boolean = true): string {
const pattern = keepSpaces ? /[^a-zA-Z0-9\s]/g : /[^a-zA-Z0-9]/g;
return text.replace(pattern, '');
}
// Remove accents
static removeAccents(text: string): string {
return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
// Sanitize filename
static sanitizeFilename(filename: string): string {
return filename.replace(/[^a-zA-Z0-9._-]/g, '_');
}
}
// 7. Regex Builder
class RegexBuilder {
private pattern: string = '';
private flags: string = '';
// Match literal
literal(text: string): this {
this.pattern += text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
return this;
}
// Match any character
anyChar(): this {
this.pattern += '.';
return this;
}
// Match digit
digit(): this {
this.pattern += '\\d';
return this;
}
// Match word character
wordChar(): this {
this.pattern += '\\w';
return this;
}
// Match whitespace
whitespace(): this {
this.pattern += '\\s';
return this;
}
// Start of string
startOfLine(): this {
this.pattern += '^';
return this;
}
// End of string
endOfLine(): this {
this.pattern += '$';
return this;
}
// Match one or more
oneOrMore(): this {
this.pattern += '+';
return this;
}
// Match zero or more
zeroOrMore(): this {
this.pattern += '*';
return this;
}
// Match zero or one
zeroOrOne(): this {
this.pattern += '?';
return this;
}
// Match range
range(min: number, max?: number): this {
if (max === undefined) {
this.pattern += `{${min}}`;
} else {
this.pattern += `{${min},${max}}`;
}
return this;
}
// Any of
anyOf(...chars: string[]): this {
this.pattern += `[${chars.join('')}]`;
return this;
}
// Capture group
capture(): this {
this.pattern += '(';
return this;
}
// End capture group
endCapture(): this {
this.pattern += ')';
return this;
}
// Named capture group
namedCapture(name: string): this {
this.pattern += `(?<${name}>`;
return this;
}
// Or
or(): this {
this.pattern += '|';
return this;
}
// Set flags
setFlags(flags: string): this {
this.flags = flags;
return this;
}
// Build regex
build(): RegExp {
return new RegExp(this.pattern, this.flags);
}
// Get pattern string
getPattern(): string {
return this.pattern;
}
}
// Usage Examples
async function demonstrateRegularExpressions() {
console.log('=== Web TypeScript Regular Expressions Examples ===\n');
// 1. Pattern matching
console.log('--- 1. Pattern Matching ---');
const text = 'Contact us at [email protected] or [email protected]';
console.log(`Text: ${text}`);
console.log(`Has email pattern: ${PatternMatcher.test(text, '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}')}`);
const matches = PatternMatcher.findAll(text, '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}');
console.log(`Emails found: ${matches ? matches.join(', ') : 'none'}`);
// 2. Validators
console.log('\n--- 2. Validators ---');
console.log(`Valid email: ${Validators.isValidEmail('[email protected]')}`);
console.log(`Valid URL: ${Validators.isValidURL('https://www.example.com')}`);
console.log(`Valid phone: ${Validators.isValidPhone('(555) 123-4567')}`);
console.log(`Valid IPv4: ${Validators.isValidIPv4('192.168.1.1')}`);
console.log(`Valid date: ${Validators.isValidDate('2024-01-15')}`);
console.log(`Valid credit card: ${Validators.isValidCreditCard('4532 1234 5678 9010')}`);
console.log(`Valid username: ${Validators.isValidUsername('user_123')}`);
console.log(`Password strength: ${Validators.getPasswordStrength('Abc123!@')}`);
// 3. Regex search
console.log('\n--- 3. Regex Search ---');
const searchText = 'The quick brown fox jumps over the lazy dog. The fox is very fast.';
const occurrences = RegexSearcher.findAll(searchText, 'fox');
console.log(`'fox' occurrences: ${occurrences.length}`);
occurrences.forEach(occ => console.log(` Found at index ${occ.index}: ${occ.match}`));
const words = RegexSearcher.findWords(searchText, 'f.*');
console.log(`Words starting with 'f': ${words.join(', ')}`);
const withContext = RegexSearcher.findWithContext(searchText, 'fox', 15);
console.log('With context:');
withContext.forEach(ctx => console.log(` ... ${ctx.context} ...`));
// 4. Text replacement
console.log('\n--- 4. Text Replacement ---');
const originalText = 'Hello world, World is beautiful. WORLD is amazing.';
console.log(`Original: ${originalText}`);
console.log(`Replace all 'world': ${RegexReplacer.replaceAll(originalText, 'world', 'earth')}`);
console.log(`Replace preserving case: ${RegexReplacer.replacePreservingCase(originalText, 'world', 'earth')}`);
const messy = 'This is a messy text.';
console.log(`Normalize whitespace: ${RegexReplacer.normalizeWhitespace(messy)}`);
// 5. Text extraction
console.log('\n--- 5. Text Extraction ---');
const extractText = 'Contact us at [email protected] or visit https://example.com. Call +1-555-123-4567. #tech @user';
console.log(`Text: ${extractText}`);
console.log(`Emails: ${TextExtractor.extractEmails(extractText).join(', ')}`);
console.log(`URLs: ${TextExtractor.extractURLs(extractText).join(', ')}`);
console.log(`Hashtags: ${TextExtractor.extractHashtags(extractText).join(', ')}`);
console.log(`Mentions: ${TextExtractor.extractMentions(extractText).join(', ')}`);
console.log(`Phones: ${TextExtractor.extractPhones(extractText).join(', ')}`);
// 6. Text sanitization
console.log('\n--- 6. Text Sanitization ---');
const html = '<p>Hello <b>World</b>!</p>';
console.log(`Original: ${html}`);
console.log(`Strip HTML: ${TextSanitizer.stripHTMLTags(html)}`);
console.log(`Escape HTML: ${TextSanitizer.escapeHTML(html)}`);
const special = 'Hello, World! @#$ %^&*()';
console.log(`Remove special: ${TextSanitizer.removeSpecialChars(special)}`);
const accented = 'café résumé naïve';
console.log(`Remove accents: ${TextSanitizer.removeAccents(accented)}`);
const filename = 'my/file:name*.txt';
console.log(`Sanitize filename: ${TextSanitizer.sanitizeFilename(filename)}`);
// 7. Regex builder
console.log('\n--- 7. Regex Builder ---');
const emailRegex = new RegexBuilder()
.startOfLine()
.capture().wordChar().oneOrMore().endCapture()
.literal('@')
.capture().wordChar().oneOrMore().endCapture()
.literal('.')
.capture().wordChar().range(2, 4).endCapture()
.endOfLine()
.build();
console.log(`Built pattern: ${emailRegex.source}`);
console.log(`Test email: ${emailRegex.test('[email protected]')}`);
const numberRegex = new RegexBuilder()
.startOfLine()
.capture().digit().oneOrMore().endCapture()
.literal('.')
.capture().digit().range(2).endCapture()
.endOfLine()
.build();
console.log(`Price pattern: ${numberRegex.source}`);
console.log(`Test price: ${numberRegex.test('19.99')}`);
console.log('\n=== All Regular Expressions Examples Completed ===');
}
// Export classes
export { PatternMatcher, Validators, RegexSearcher, RegexReplacer, TextExtractor, TextSanitizer, RegexBuilder };
export { demonstrateRegularExpressions };