Regular Expressions Cookbook, 2nd Edition
by Steven Levithan
Published by
O'Reilly Media, Inc., 2012
and
Tags
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 |
\\\0
| 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\\.>"); // -> trueThis 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», «\0», or «\g<0>») is used to restore the
matched character along with a preceding backslash. In Perl, $& is actually a variable, and using it
with any regular expression imposes a global performance penalty on all
regular expressions. If $& is
used elsewhere in your Perl program, it’s OK to use it as much as you
want because you’ve already paid the price. Otherwise, it’s probably
better to wrap the entire regex in a capturing group, and use $1 instead of $& in the replacement.
As explained in Block escape, you can create a
block escape sequence within a regex using ‹\Q⋯\E›. However, block escapes are only
supported by Java, PCRE, and Perl, and even in those languages block
escapes are not foolproof. For complete safety, you’d still need to
escape any occurrence of \E within the string
you plan to embed in your regex. In most cases it’s probably easier to
just use the cross-language approach of escaping all regex
metacharacters.
Recipe 2.1 discusses how to match literal characters and escape metacharacters. However, its list of characters that need to be escaped is shorter since it doesn’t concern itself with characters that may need to be escaped in free-spacing mode or when dropped into an arbitrary, longer pattern.
The example JavaScript solution in Recipe 5.2 creates a function that escapes any regular expression metacharacters within words to be searched for. It uses the shorter list of special characters from Recipe 2.1.
Techniques used in the regular expression and replacement text in this recipe are discussed in Chapter 2. Recipe 2.3 explains character classes. Recipe 2.20 explains how to insert the regex match into the replacement text.