We can make use of the negate
argument in str_subset
.
library(stringr)
str_subset(countries, pattern = "(?<=(?i)e)((?i)e)|^([^Ee]+)$",
negate = TRUE)
#[1] "Lebanon" "Mexico" "Egypt" "France" "FRANCE"
Here, we match the case insensitive ((?i)
) 'e' that follows a case insenstive 'e' (showed in the regex lookaround ((?<=
) or (|
) characters that are not a "E" or "e" from the start (^
) to end ($
) of the string (essentially matching words with no "E" or "e" character) and use negate = TRUE
to reverse the matching words
Or using str_count
countries[str_count(countries, "(?<!e)(?i)e(?!=e)") == 1]
#[1] "Lebanon" "Mexico" "Egypt" "France" "FRANCE"
EDIT: Included some more edges cases as mentioned by @G5W
data
countries <- c("USA", "Lebanon", "Greece", "Mexico", "Egypt", "France", "FRANCE")