EN
TypeScript - escape special characters in regular expression pattern
3
points
In this short article, we would like to show how to escape special characters from patterns that we want to use with regular expressions in TypeScript.
Practical example:
const SPECIAL_CHARACTERS_EXPRESSION: RegExp = /[.*+?^${}()\[\]\\|]/g;
// Escapes regular expression pattern special characters in the indicated string.
//
const escapePattern = (pattern: string): string => {
return pattern.replace(SPECIAL_CHARACTERS_EXPRESSION, '\\$&');
};
// Usage example:
const pattern: string = escapePattern('.*');
const expression: RegExp = new RegExp(pattern, 'g');
const text: string = 'this is example text with .* and .* and .*';
const result: string[] = text.match(expression);
console.log(pattern); // '\.\*'
console.log(result); // ['.*', '.*', '.*']
Output:
\.\*
[ '.*', '.*', '.*' ]
Hint: the above approach is useful when we want to escape all special characters automatically.
Manual escape
We can escape special characters manually by using \
or \\
before them in patterns.
1. Escape in string pattern
In strings, we should escape special characters using \\
.
const expression: RegExp = new RegExp('\\.\\*', 'g');
const text: string = 'this is example text with .* and .* and .*';
const result: string[] = text.match(expression);
console.log(result); // ['.*', '.*', '.*']
Output:
['.*', '.*', '.*']
2. Escape in syntax pattern
In syntax patterns, we should escape special characters using \
.
const expression: RegExp = /\.\*/g;
const text: string = 'this is example text with .* and .* and .*';
const result: string[] = text.match(expression);
console.log(result); // ['.*', '.*', '.*']
Output:
[ '.*', '.*', '.*' ]
Optimal solutions
1. Best performance
escapePattern()
function is faster by about 2.5x than the replace-based version.
// Escapes regular expression pattern special characters in the indicated string.
//
const escapePattern = (pattern: string): string => {
let result = '';
for (let i = 0; i < pattern.length; ++i) {
const entry = pattern[i];
switch (entry) {
case '.':
case '*':
case '+':
case '?':
case '^':
case '$':
case '{':
case '}':
case '(':
case ')':
case '[':
case ']':
case '|':
case '\\':
result += '\\' + entry;
break;
default:
result += entry;
break;
}
}
return result;
};
// Usage example:
const pattern: string = escapePattern('.*');
const expression: RegExp = new RegExp(pattern, 'g');
const text: string = 'this is example text with .* and .* and .*';
const result: string[] = text.match(expression);
console.log(pattern); // '\.\*'
console.log(result); // ['.*', '.*', '.*']
Output:
\.\*
[ '.*', '.*', '.*' ]
2. Quite good performance:
escapePattern()
function is faster by about 1.5x than the replace-based version.
const SPECIAL_CHARACTERS: Record<string, number> = {'.': 1, '*': 1, '+': 1, '?': 1, '^': 1, '$': 1, '{': 1, '}': 1, '(': 1, ')': 1, '[': 1, ']': 1, '|': 1, '\\': 1};
// Escapes regular expression pattern special characters in the indicated string.
//
const escapePattern = (pattern: string): string => {
let result = '';
for (let i = 0; i < pattern.length; ++i) {
const entry = pattern[i];
result += SPECIAL_CHARACTERS[entry] ? '\\' + entry : entry;
}
return result;
};
// Usage example:
const pattern: string = escapePattern('.*');
const expression: RegExp = new RegExp(pattern, 'g');
const text: string = 'this is example text with .* and .* and .*';
const result: string[] = text.match(expression);
console.log(pattern); // '\.\*'
console.log(result); // ['.*', '.*', '.*']
Output:
\.\*
[ '.*', '.*', '.*' ]