Match substring with regex for one or more capitalised words between quotation marks

Viewed 60

I have the following string:

example_string <- "In this document, Defined Terms are quotation marks, followed by definition. \"Third Party Software\" is software owned by third parties. \"USA\" the United States of America. \"Breach of Contract\" is in accordance with the Services Description."

I want to extract every substring which is at least partially capitalised and is sandwiched by quotation marks. So the output should be:

"Third Party Software"  "USA"  "Breach of Contract"

I got as far as this with the regex:

str_extract_all(example_string, "(?:\")\\w(\\s*\\w+)*")

[[1]]
[1] "\"Third Party Software" "\"USA"                  "\"Breach of Contract"

I can't figure out a way to avoid matching the opening escaped quotation mark \". I know I can just add a gsub line to clean it out after extracting the defined terms, but I think there must be a way to do it all in one regex call.

Any suggestions greatly appreciated!

1 Answers

In your expression, (?:")\w(\s*\w+)*", you match and consume the " char using a non-capturing (?:") group. Thus, it lands in the match value.

You might have wanted to use

"(?<=\")\\w(\\s*\\w+)*"

where (?<=") is a positive lookbehind that matches a location that is immediately preceded with a " char.

However, when you have identical single char right and left delimiters, I'd rather use a capturing approach.

You can use stringr::str_match_all with

"(\p{Lu}[^"]*)"

Or, it can also be your pattern, a bit modified:

"(\p{Lu}\w*(?:\s+\w+)*)"

See the regex demo, or this demo. Details:

  • " - a " char
  • (\p{Lu}[^"]*) - Capturing group 1:
    • \p{Lu} - any Unicode uppercase letter
    • [^"]* - any zero or more chars other than "
  • \w*(?:\s+\w+)* - 0+ letters, digits, underscores, and then 0+ occurrences of 1+ whitespaces followed with 1+ letters, digits, underscores
  • " - a " char.

See the R demo online:

library(stringr)
example_string <- "In this document, Defined Terms are quotation marks, followed by definition. \"Third Party Software\" is software owned by third parties. \"USA\" the United States of America. \"Breach of Contract\" is in accordance with the Services Description."
res <- str_match_all(example_string, '"(\\p{Lu}[^"]*)"')
unlist(lapply(res, function(x) x[,-1]))
## => [1] "Third Party Software" "USA"                  "Breach of Contract"
Related