rguides

stringr::str_extract()

str_extract(string, pattern, regex = TRUE)

The str_extract() function from stringr extracts the first matching pattern from a string. It returns the actual matched text, not just TRUE/FALSE like str_detect().

Syntax

str_extract(string, pattern, regex = TRUE)

Parameters

ParameterTypeDefaultDescription
stringcharacterRequiredA character vector to search
patternpatternRequiredA pattern to look for (regex, fixed, or coll)
regexlogicalTRUEIf TRUE, pattern is interpreted as a regular expression

Examples

Basic usage

library(stringr)

# Extract a substring
strings <- c("abc123def", "xyz456", "789uvw")
str_extract(strings, "[a-z]+")
# [1] "abc" "xyz" "uvw"

The next example demonstrates extracting numbers, building on the pattern established above and showing how the function behaves with a different set of inputs or arguments. Working through these variations step by step reinforces how each parameter affects the output and builds the muscle memory you need to reach for the right function in your own R scripts without having to consult the documentation every time.

Extracting numbers

# Extract digits from strings
str_extract(c("item123", "price999", "qty42"), "[0-9]+")
# [1] "123" "999" "42"

The next example demonstrates using regex capture groups, building on the pattern established above and showing how the function behaves with a different set of inputs or arguments. Working through these variations step by step reinforces how each parameter affects the output and builds the muscle memory you need to reach for the right function in your own R scripts without having to consult the documentation every time.

Using regex capture groups

# Extract the username from an email
emails <- c("user@example.com", "admin@domain.org", "test@site.net")
str_extract(emails, "^[^@]+")
# [1] "user" "admin" "test"

The next example demonstrates extracting dates, building on the pattern established above and showing how the function behaves with a different set of inputs or arguments. Working through these variations step by step reinforces how each parameter affects the output and builds the muscle memory you need to reach for the right function in your own R scripts without having to consult the documentation every time.

Extracting dates

# Extract dates in YYYY-MM-DD format
dates <- c("2024-01-15", "2023-12-25", "2025-06-30")
str_extract(dates, "[0-9]{4}-[0-9]{2}-[0-9]{2}")
# [1] "2024-01-15" "2023-12-25" "2025-06-30"

The next example demonstrates using with dplyr mutate, building on the pattern established above and showing how the function behaves with a different set of inputs or arguments. Working through these variations step by step reinforces how each parameter affects the output and builds the muscle memory you need to reach for the right function in your own R scripts without having to consult the documentation every time.

Using with dplyr mutate

library(dplyr)

df <- data.frame(
  text = c("Order #12345", "Invoice #67890", "Ref #ABCDE")
)

df %>%
  mutate(order_number = str_extract(text, "[0-9]+"))
#             text order_number
# 1  Order #12345        12345
# 2 Invoice #67890        67890
# 3    Ref #ABCDE        ABCDE

The next example demonstrates using fixed() for exact matching, building on the pattern established above and showing how the function behaves with a different set of inputs or arguments. Working through these variations step by step reinforces how each parameter affects the output and builds the muscle memory you need to reach for the right function in your own R scripts without having to consult the documentation every time.

Using fixed() for exact matching

# Extract literal strings (not regex)
str_extract("Hello World", fixed("World"))
# [1] "World"

# Useful for case-insensitive matching
str_extract("Hello WORLD", fixed("world", ignore_case = TRUE))
# [1] "WORLD"

The next example demonstrates str_extract_all, building on the pattern established above and showing how the function behaves with a different set of inputs or arguments. Working through these variations step by step reinforces how each parameter affects the output and builds the muscle memory you need to reach for the right function in your own R scripts without having to consult the documentation every time.

str_extract_all

For extracting all matches (not just the first), use str_extract_all():

strings <- c("abc123def456", "xyz789", "123")

# Extract all digit sequences
str_extract_all(strings, "[0-9]+")
# [[1]]
# [1] "123" "456"
# [[2]]
# [1] "789"
# [[3]]
# [1] "123"

# Simplify to vector with simplify = TRUE
str_extract_all(strings, "[0-9]+", simplify = TRUE)
#      [,1]  [,2]
# [1,] "123" "456"
# [2,] "789" ""  
# [3,] "123" ""

Common use cases

  • Parsing structured text (dates, emails, phone numbers)
  • Extracting IDs from log files
  • Pulling specific parts from formatted strings
  • Data cleaning and standardization

stringr::str_extract() in practice

str_extract() returns the first match of a pattern in each string, or NA if there is no match. str_extract_all() returns all matches as a list. For extracting a specific capture group, use str_match(), which returns a matrix with the full match in column 1 and each capture group in subsequent columns.

A common pattern: extracting structured data from semi-structured text. str_extract(x, "\\d{4}-\\d{2}-\\d{2}") extracts ISO dates. str_extract(x, "\\d+\\.?\\d*") extracts the first number. Combined with as.numeric() or as.Date(), this converts extracted strings to the appropriate type.

str_extract() returns NA rather than "" for non-matches, which makes it easy to check for successful extraction: !is.na(str_extract(x, pattern)) is equivalent to str_detect(x, pattern). After extraction, !is.na() or tidyr::drop_na() can filter out rows where the pattern was not found.

For extracting multiple patterns from the same strings, apply str_extract() separately for each pattern and combine with mutate(): mutate(df, date = str_extract(text, date_pattern), amount = str_extract(text, amount_pattern)). This is more maintainable than a single complex regex with multiple capture groups, especially when patterns are reused across the codebase.

str_extract() returns the first match per string. Use str_extract_all() to return all matches, which gives a list of character vectors. Set simplify = TRUE in str_extract_all() to get a matrix instead of a list. Capturing groups in the pattern do not affect what is extracted, the full match is returned. To extract a specific group, use str_match(), which returns a matrix with the full match and each captured group in separate columns.

Extracting vs matching

str_extract() returns the matched text; str_detect() returns a logical indicating whether a match exists. Use str_extract() when you need the actual matched value — pulling a date from a sentence, extracting a code from a longer string. Use str_detect() for filtering or conditional logic where you only need to know if the pattern exists.

str_extract_all() returns all non-overlapping matches in each string as a list of character vectors. The list structure handles the case where different strings contain different numbers of matches. Combining with purrr::map_chr() or using unnest() after extracting produces a flat character vector when you expect exactly one match per string or want all matches in a single column.

See also