You want to use a literal string provided by a user or from some other source as part of a regular expression. However, you want to escape all regular expression metacharacters within the string before embedding it in your regex, to avoid any unintended consequences.
By adding a backslash before any characters that potentially have special meaning within a regular expression, you can safely use the resulting pattern to match a literal sequence of characters. Of the programming languages covered by this book, all except JavaScript have a built-in function or method to perform this task (listed in Table 5-3). However, for the sake of completeness, we’ll show how to pull this off using your own regex, even in the languages that have a ready-made solution.
Table 5-3 lists the built-in functions and methods designed to solve this problem.
Table 5-3. Built-in solutions for escaping regular expression metacharacters
Language | Function |
---|---|
C#, VB.NET | |
Java | |
XRegExp | |
Perl | |
PHP | |
Python | |
Ruby | |
Notably absent from the list is JavaScript (without XRegExp), which does not have a native function designed for this purpose.
Although it’s best to use a built-in solution if available, you can pull this off on your own by using the following regular expression along with the appropriate replacement string (shown next). Make sure to replace all matches, rather than only the first. Recipe 3.15 shows code for replacing matches with strings that contain backreferences. You’ll need a backreference here to bring back the matched special character along with a preceding backslash:
[[]{}()*+?.\|^$-,&#s]
Regex options: None |
Regex flavors: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby |
The following replacement strings contain a literal backslash character. The strings are shown without the extra backslashes that may be needed to escape backslashes when using string literals in some programming languages. See Recipe 2.19 for more details about replacement text flavors.
$&
Replacement text flavors: .NET, JavaScript |
$0
Replacement text flavors: .NET, XRegExp |
\$&
Replacement text flavor: Perl |
\$0
Replacement text flavors: Java, PHP |
\
Replacement text flavors: PHP, Ruby |
\&
Replacement text flavor: Ruby |
\g<0>
Replacement text flavor: Python |
Here’s an example of how you can put the regular
expression and replacement string to use to create a static method
called RegExp.escape()
in
JavaScript:
RegExp.escape = function(str) { return str.replace(/[[]{}()*+?.\|^$-,&#s]/g, "\$&"); }; // Test it... var str = "<Hello World.>"; var escapedStr = RegExp.escape(str); alert(escapedStr == "<Hello\ World\.>"); // -> true
This recipe’s regular expression puts all the regex metacharacters inside a single character class. Let’s take a look at each of those characters, and examine why they need to be escaped. Some are less obvious than others:
[ { ( )
‹[
›
creates a character class. ‹{
›
creates an interval quantifier and is also used with some other
special constructs, such as Unicode properties. ‹(
› and ‹)
› are used for grouping,
capturing, and other special constructs.
* + ?
These three characters are quantifiers that repeat their preceding element zero or more, one or more, or between zero and one time, respectively. The question mark is also used after an opening parenthesis to create special groupings and other constructs (the same is true for the asterisk in Perl 5.10 and PCRE 7).
. |
A dot matches any character within a line or string, a backslash makes a special character literal or a literal character special, and a vertical bar alternates between multiple options.
^ $
The caret and dollar symbols are anchors that match the start or end of a line or string. The caret can also negate a character class.
The remaining characters matched by the regular expression are only special in special circumstances. They’re included in the list to err on the side of caution.
]
A right square bracket ends a character class. Normally, this would not need to be escaped on its own, but doing so avoids unintentionally ending a character class when embedding text inside one. Keep in mind that if you do embed text inside a character class, the resulting regex will not match the embedded string, but rather any one of the characters in the embedded string.
-
A hyphen creates a range within a character class. It’s escaped here to avoid inadvertently creating ranges when embedding text in the middle of a character class.
}
A right curly bracket ends an interval quantifier or other special construct. Since most regular expression flavors treat curly brackets as literal characters if they do not form a valid quantifier, it’s possible to create a quantifier where there was none before when inserting literal text in a regex if you don’t escape both ends of curly brackets.
,
A comma is used inside an interval quantifier such as
‹{1,5}
›. It’s
possible (though a bit unlikely) to create a quantifier where
there was none before when inserting literal text in a regex if
you don’t escape commas.
&
The ampersand is included in the list because two ampersands in a row are used for character class intersection in Java (see Flavor-Specific Features). In other programming languages, it’s safe to remove the ampersand from the list of characters that need to be escaped, but it doesn’t hurt to keep it.
#
and
whitespaceThe pound sign and whitespace (matched by ‹s
›) are metacharacters only
if the free-spacing option is enabled. Again, it doesn’t hurt to
escape them anyway.
As for the replacement text, one of five tokens («$&
», «&
», «$0
», «