How to detect a string in all caps and convert it to start case
r, regex, string
Solution
Part of this is a demo example in the package `gsubfn`. You can run it after installing the package with `demo(gsubfn::gsubfn-lower)`.
x <- c('One', 'TWO', 'THREE / FOUR', 'ÁÁÁ')
library(gsubfn)
## find indices of vector where there are no lowercase letters
## (therefore all letters must be uppercase)
idx <- grep("[[:lower:]]", x, invert = TRUE)
## in these indices, run tolower on characters
## that do not follow a word boundary \\B
x[idx] <- gsubfn("\\B.", tolower, x[idx], perl = TRUE)
# [1] "One" "Two" "Three / Four" "Ááá"
Both `\B` and `[:lower:]` are locale-dependent by `Sys.getlocale("LC_CTYPE")`. Mine is `"English_United States.1252"`. Your mileage may vary.
Problem
Say I have the following vector ``` x <- c('One', 'TWO', 'THREE / FOUR') ``` I want to convert `TWO` and `THREE / FOUR` to `Two` and `Three / Four`, respectively. I've taken a look into `casefold()` and the whole `chartr()` help page but couldn't figure this out. In my real problem, I have a vector of 1500 strings in which I intend to detect entries written in all caps (I know many of them include a slash just like the one in the example above) and convert them to start case. One thing I can do is run `grepl('^[A-Z]+$', x)` (as suggested by tenub), but it doesn't detect the `THREE / FOUR` as being all caps (it yields `[1] FALSE TRUE FALSE`). From what I've seen, just the presence of a space is enough to have this return `FALSE`. Removing the anchor `grepl('[A-Z]+$', x)` (as suggested by TheGreatCO) works for the example above, but fails in the next: ``` y <- "Imposto Territorial Rural - ITR" grepl('[A-Z]+', y) [1] TRUE ``` Moreover, elements containing accents are always left out, no matter what I try: ``` z <- c('Á') grepl('[A-Z]+', z) [1] FALSE ```