I was hoping this could be done with a single regular expression like the following:
mtcars %>%
select_at(vars(matches("^c(?!.*ar)")), toupper) %>%
names()
^c means the first character has to be c. Then (?!.*ar) is a negative lookahead that matches only strings that don't contain ar anywhere after the initial c.
However, the above code results in an "invalid regular expression" error.
If this were one of the grep functions, you could avoid this with a perl=TRUE argument, but that doesn't appear to be available in the standard tidyselect helpers (but see update below; it's now available in the development version). Based on this SO answer, here's a select helper that uses perl regular expressions:
matches2 <- function (match, ignore.case = TRUE, vars = current_vars()) {
tidyselect:::grep_vars(match, vars, ignore.case=ignore.case, perl=TRUE)
}
Then we can do:
mtcars %>%
select_at(vars(matches2("^c(?!.*ar)")), toupper) %>%
names()
[1] "CYL"
Update: The development version of tidyselect has a new perl=TRUE argument for matches. With the development version, you can now do:
mtcars %>%
select_at(vars(matches("^c(?!.*ar)", perl=TRUE)), toupper) %>%
names()