Regular expressions for R users

regex
stringr
Regular expressions let you search and manipulate strings based on patterns rather than just literal matches. This is often straightforward, but when it’s not, watch out!
Author

Andrew Gard

Published

August 24, 2026

Searching and manipulating strings (those things that make up character vectors) is easy as long as you only need to match specific sequences of letters and numbers. To match patterns rather than specific substrings or to search symbols, you’ll need to use regular expressions, or regex.

Throughout this post, I’ll make use three stringr functions: str_subset, str_detect, and str_extract, and a few elements of the sentences vector.

library(stringr)

sentences <- sentences[1:10]
sentences
 [1] "The birch canoe slid on the smooth planks." 
 [2] "Glue the sheet to the dark blue background."
 [3] "It's easy to tell the depth of a well."     
 [4] "These days a chicken leg is a rare dish."   
 [5] "Rice is often served in round bowls."       
 [6] "The juice of lemons makes fine punch."      
 [7] "The box was thrown beside the parked truck."
 [8] "The hogs were fed chopped corn and garbage."
 [9] "Four hours of steady work faced us."        
[10] "A large size in stockings is hard to sell." 
str_subset(sentences, "of") # keep only elements with a match
[1] "It's easy to tell the depth of a well."
[2] "Rice is often served in round bowls."  
[3] "The juice of lemons makes fine punch." 
[4] "Four hours of steady work faced us."   
str_detect(sentences, "of") # TRUE when an element matches, FALSE otherwise
 [1] FALSE FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE
str_extract(sentences, "of") # pull out matching substrings
 [1] NA   NA   "of" NA   "of" "of" NA   NA   "of" NA  

Special characters

The following characters (all of which are explained below) have special meanings and can’t be searched literally.

. \ | ( ) [ { ^ $ * + ? 

For instance, a dot matches with any character, which explains the following output.

str_extract(sentences, ".")
 [1] "T" "G" "I" "T" "R" "T" "T" "T" "F" "A"

In order to match these metacharacters, precede them with two slashes, like this:

str_extract(sentences, "\\.")
 [1] "." "." "." "." "." "." "." "." "." "."

Position and relative position

To specify that a substring comes at the beginning of a string, use “^”. To specify that it comes at the end, use “$”.

str_subset(fruit, "^re")
[1] "redcurrant"
str_subset(fruit, "er$") # note order
[1] "bell pepper"  "chili pepper" "cucumber"    

As mentioned above, a dot indicates that substrings are separated by an arbitrary character.

str_extract(sentences, "s.o")
 [1] "smo" NA    NA    NA    "s o" NA    NA    NA    "s o" "sto"

Character sets

Use brackets to allow multiple options for the character to be matched.

str_subset(sentences, "[oe]n")
[1] "The birch canoe slid on the smooth planks."
[2] "These days a chicken leg is a rare dish."  
[3] "Rice is often served in round bowls."      
[4] "The juice of lemons makes fine punch."     
str_extract(sentences, "[oe]n")
 [1] "on" NA   NA   "en" "en" "on" NA   NA   NA   NA  

Ranges of letters and numbers are allowed.

str_subset(sentences, "[a-j]o")
[1] "Rice is often served in round bowls."       
[2] "The box was thrown beside the parked truck."
[3] "The hogs were fed chopped corn and garbage."
[4] "Four hours of steady work faced us."        
str_extract(sentences, "[a-j]o")
 [1] NA   NA   NA   NA   "bo" NA   "bo" "ho" "ho" NA  

Inside of brackets, “^” represents negation.

str_extract(sentences, "[^a-j]o")
 [1] "no" "to" "to" NA   " o" " o" "ro" NA   "Fo" "to"

Character classes

It’s also possible to specify classes of characters. “\d” matches any digit and “\w” matches and word character (a-z, A-Z, 0-9, and underscore), while “\D” and “\W” will match anything except digits and word characters, respectively. Many other classes are available. Enter ?regex for a full list.

The role of “\” in Quarto

If you write “\d” in a Quarto document, it won’t render properly. This is because Quarto interprets the slash as an escape character. To actually render this string, use “\\d” instead.

Similarly, to render a slash, use \\.

Matching whitespace

Use \\s for space, \\t for tab, and \\n for a new line.

str_subset(sentences, "e\\sb")
[1] "The birch canoe slid on the smooth planks." 
[2] "Glue the sheet to the dark blue background."
[3] "The box was thrown beside the parked truck."

Repetition

Use curly braces to indicate how many times in a row a character must appear.

str_subset(sentences, "e{2}")
[1] "Glue the sheet to the dark blue background."

Use “+” to indicate at least one occurrence, possibly more.

str_subset(sentences, "she+t")
[1] "Glue the sheet to the dark blue background."

To indicate a character is optional, use “?”. For instance, the next command detects both “the” and “often”.

str_extract(sentences, "th?e")
 [1] "the" "the" "te"  NA    "te"  NA    "the" NA    "te"  NA   

Finally, “*” indicates an optional character that may occur more than once.

str_extract(sentences, "she*")
 [1] NA     "shee" NA     "sh"   NA     NA     NA     NA     NA     NA    

Notice that these symbols come after the characters they refer to, unlike “\” which comes before.

Combining substrings with |

Use the pipe to indicate an “or” statement. Expressions on either side are grouped by default.

str_subset(sentences, "chicken|hog")
[1] "These days a chicken leg is a rare dish."   
[2] "The hogs were fed chopped corn and garbage."

You can still group using parentheses, though.

str_subset(sentences, "(chicken|hog)s")
[1] "The hogs were fed chopped corn and garbage."

Want more?

If something here isn’t clear, there’s a good chance you’ll find an explanation in my vid on the subject: