R - Delete string in character vector that begins with capital letter

Viewed 109

I have a df:

df <- c("hello goodbye Delete Me", "Another Sentence good program", "hello world The End")

I want this:

c("hello goodbye", "good program", "hello world")

I have tried:

df <- grep("^[A-Z]", df, invert = TRUE, value = TRUE)

but this deletes the entire character that starts with a capital letter:

c("hello goodbye Delete Me", "hello world The End")

How do I do this?

4 Answers

You can use -

trimws(gsub('[A-Z]\\w+', '', df))
#[1] "hello goodbye" "good program"  "hello world" 

You may use the following regex pattern, and then replace with just a single space:

\s*[A-Z]\w+\s*

This will capture all words beginning with capital letters, along with any whitespace which might appear on either side. The outer call to trimws() is there to remove any spaces which might remain at the very start or end, as a leftover of the replacement logic.

x <- c("nice to meet You however", "cat Ran away", "Cat", "Dog")
trimws(gsub('\\s*[A-Z]\\w+\\s*', ' ', x))

[1] "nice to meet however" "cat away"             ""                    
[4] ""

How about:

library(stringr)
str_extract(df, "[^ ]+ [^ ]+")

Output:

[1] "hello goodbye"    "Another Sentence" "hello world" 

You can use the following three solutions:

df <- c("hello goodbye Delete Me", "Another Sentence good program", "hello world The End", "an iPhone", "Ещё Одно слово")

## Base R gsub with default TRE regex engine:
trimws(gsub("\\s*\\b[[:upper:]][[:alpha:]]*\\b", "", df))

## Base R gsub with PCRE regex engine:
trimws(gsub("(*UCP)\\s*\\b\\p{Lu}\\p{L}*\\b", "", df, perl=TRUE))

## stringr::str_replace_all with ICU regex engine:
library(stringr)
str_trim(str_replace_all(df, "\\s*\\b\\p{Lu}\\p{L}*\\b", ""))

Output is [1] "hello goodbye" "good program" "hello world" "an iPhone" "слово" for all three. Please note that the word boundary is crucial to handle words like iPhone correctly.

See the online R demo. Also, see the PCRE regex demo showing how the regex works (you can go here to watch the internals of the regex engine).

Regex details:

  • \s* - zero or more whitespace chars
  • \b - a word boundary
  • [[:upper:]] / \p{Lu} - any Unicode uppercase letter
  • [[:alpha:]]* - any zero or more letters
  • \b - a word boundary

The (*UCP) in the PCRE regex enables the Unicode property classes in the regex.

trimws is necessary to remove the leading/trailing spaces in case they appear after the replacements.

Related