I want to match a regular expression special character, \^$.?*|+()[{
. I tried:
x <- "a[b"
grepl("[", x)
## Error: invalid regular expression '[', reason 'Missing ']''
(Equivalently stringr::str_detect(x, "[")
or stringi::stri_detect_regex(x, "[")
.)
Doubling the value to escape it doesn't work:
grepl("[[", x)
## Error: invalid regular expression '[[', reason 'Missing ']''
Neither does using a backslash:
grepl("\[", x)
## Error: '\[' is an unrecognized escape in character string starting ""\["
How do I match special characters?
Some special cases of this in questions that are old and well written enough for it to be cheeky to close as duplicates of this:
Escaped Periods In R Regular Expressions
How to escape a question mark in R?
escaping pipe ("|") in a regex
I think the easiest way to match the characters like
are using character classes from within R. Consider the following to clean column headers from a data file, which could contain spaces, and punctuation characters:
This approach allows us to string character classes to match punctation characters, in addition to whitespace characters, something you would normally have to escape with
\\
to detect. You can learn more about the character classes at this cheatsheet below, and you can also type in?regexp
to see more info about this.https://www.rstudio.com/wp-content/uploads/2016/09/RegExCheatsheet.pdf
Escape with a double backslash
R treats backslashes as escape values for character constants. (... and so do regular expressions. Hence the need for two backslashes when supplying a character argument for a pattern. The first one isn't actually a character, but rather it makes the second one into a character.) You can see how they are processed using
cat
.Further reading: Escaping a backslash with a backslash in R produces 2 backslashes in a string, not 1
To use special characters in a regular expression the simplest method is usually to escape them with a backslash, but as noted above, the backslash itself needs to be escaped.
To match backslashes, you need to double escape, resulting in four backslashes.
The
rebus
package contains constants for each of the special characters to save you mistyping slashes.For more examples see:
Your problem can be solved this way:
Form a character class
You can also wrap the special characters in square brackets to form a character class.
Two of the special characters have special meaning inside character classes:
\
and^
.Backslash still needs to be escaped even if it is inside a character class.
Caret only needs to be escaped if it is directly after the opening square bracket.
rebus
also lets you form a character class.Use a pre-existing character class
If you want to match all punctuation, you can use the
[:punct:]
character class.stringi
maps this to the Unicode General Category for punctuation, so its behaviour is slightly different.You can also use the cross-platform syntax for accessing a UGC.
Use \Q \E escapes
Placing characters between
\\Q
and\\E
makes the regular expression engine treat them literally rather than as regular expressions.rebus
lets you write literal blocks of regular expressions.Don't use regular expressions
Regular expressions are not always the answer. If you want to match a fixed string then you can do, for example: