suppressPackageStartupMessages(library("tidyverse"))
package 㤼㸱tidyverse㤼㸲 was built under R version 3.6.3

1. In the previous example, you might have noticed that the regular expression matched “flickered”, which is not a color. Modify the regex to fix the problem.

This was the original color match pattern:

colours <- c("red", "orange", "yellow", "green", "blue", "purple")
colour_match <- str_c(colours, collapse = "|")

It matches “flickered” because it matches “red”. The problem is that the previous pattern will match any word with the name of a color inside it. We want to only match colors in which the entire word is the name of the color. We can do this by adding a \b (to indicate a word boundary) before and after the pattern:

colour_match2 <- str_c("\\b(", str_c(colours, collapse = "|"), ")\\b")
colour_match2
[1] "\\b(red|orange|yellow|green|blue|purple)\\b"
more2 <- sentences[str_count(sentences, colour_match) > 1]
str_view_all(more2, colour_match2, match = TRUE)
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

2. From the Harvard sentences data, extract:

1. The first word from each sentence.

2. All words ending in ing.

3. All plurals.

The answer to each part follows.

1. Finding the first word in each sentence requires defining what a pattern constitutes a word. For the purposes of this question, I’ll consider a word any contiguous set of letters. Since str_extract() will extract the first match, if it is provided a regular expression for words, it will return the first word.

str_extract(sentences, "[A-ZAa-z]+") %>% head()
[1] "The"   "Glue"  "It"    "These" "Rice"  "The"  

However, the third sentence begins with “It’s”. To catch this, I’ll change the regular expression to require the string to begin with a letter, but allow for a subsequent apostrophe.

str_extract(sentences, "[A-Za-z][A-Za-z']*") %>% head()
[1] "The"   "Glue"  "It's"  "These" "Rice"  "The"  

2. This pattern finds all words ending in ing.

pattern <- "\\b[A-Za-z]+ing\\b"
sentences_with_ing <- str_detect(sentences, pattern)
unique(unlist(str_extract_all(sentences[sentences_with_ing], pattern))) %>%
  head()
[1] "spring"  "evening" "morning" "winding" "living"  "king"   

3. Finding all plurals cannot be correctly accomplished with regular expressions alone. Finding plural words would at least require morphological information about words in the language. See WordNet for a resource that would do that. However, identifying words that end in an “s” and with more than three characters, in order to remove “as”, “is”, “gas”, etc., is a reasonable heuristic.

unique(unlist(str_extract_all(sentences, "\\b[A-Za-z]{3,}s\\b"))) %>%
  head()
[1] "planks" "days"   "bowls"  "lemons" "makes"  "hogs"  
LS0tDQp0aXRsZTogIkV4dHJhY3QgbWF0Y2hlcyINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KYGBge3J9DQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSgidGlkeXZlcnNlIikpDQpgYGANCg0KIyMjIDEuIEluIHRoZSBwcmV2aW91cyBleGFtcGxlLCB5b3UgbWlnaHQgaGF2ZSBub3RpY2VkIHRoYXQgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBtYXRjaGVkIOKAnGZsaWNrZXJlZOKAnSwgd2hpY2ggaXMgbm90IGEgY29sb3IuIE1vZGlmeSB0aGUgcmVnZXggdG8gZml4IHRoZSBwcm9ibGVtLg0KDQpUaGlzIHdhcyB0aGUgb3JpZ2luYWwgY29sb3IgbWF0Y2ggcGF0dGVybjoNCg0KYGBge3J9DQpjb2xvdXJzIDwtIGMoInJlZCIsICJvcmFuZ2UiLCAieWVsbG93IiwgImdyZWVuIiwgImJsdWUiLCAicHVycGxlIikNCmNvbG91cl9tYXRjaCA8LSBzdHJfYyhjb2xvdXJzLCBjb2xsYXBzZSA9ICJ8IikNCmBgYA0KDQpJdCBtYXRjaGVzIOKAnGZsaWNrZXJlZOKAnSBiZWNhdXNlIGl0IG1hdGNoZXMg4oCccmVk4oCdLiBUaGUgcHJvYmxlbSBpcyB0aGF0IHRoZSBwcmV2aW91cyBwYXR0ZXJuIHdpbGwgbWF0Y2ggYW55IHdvcmQgd2l0aCB0aGUgbmFtZSBvZiBhIGNvbG9yIGluc2lkZSBpdC4gV2Ugd2FudCB0byBvbmx5IG1hdGNoIGNvbG9ycyBpbiB3aGljaCB0aGUgZW50aXJlIHdvcmQgaXMgdGhlIG5hbWUgb2YgdGhlIGNvbG9yLiBXZSBjYW4gZG8gdGhpcyBieSBhZGRpbmcgYSBgXGJgICh0byBpbmRpY2F0ZSBhIHdvcmQgYm91bmRhcnkpIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIHBhdHRlcm46DQoNCmBgYHtyfQ0KY29sb3VyX21hdGNoMiA8LSBzdHJfYygiXFxiKCIsIHN0cl9jKGNvbG91cnMsIGNvbGxhcHNlID0gInwiKSwgIilcXGIiKQ0KY29sb3VyX21hdGNoMg0KbW9yZTIgPC0gc2VudGVuY2VzW3N0cl9jb3VudChzZW50ZW5jZXMsIGNvbG91cl9tYXRjaCkgPiAxXQ0Kc3RyX3ZpZXdfYWxsKG1vcmUyLCBjb2xvdXJfbWF0Y2gyLCBtYXRjaCA9IFRSVUUpDQpgYGANCg0KIyMjIDIuIEZyb20gdGhlIEhhcnZhcmQgc2VudGVuY2VzIGRhdGEsIGV4dHJhY3Q6DQoNCioqMS4gVGhlIGZpcnN0IHdvcmQgZnJvbSBlYWNoIHNlbnRlbmNlLioqDQoNCioqMi4gQWxsIHdvcmRzIGVuZGluZyBpbiBpbmcuKioNCg0KKiozLiBBbGwgcGx1cmFscy4qKg0KDQpUaGUgYW5zd2VyIHRvIGVhY2ggcGFydCBmb2xsb3dzLg0KDQoqKjEuKiogRmluZGluZyB0aGUgZmlyc3Qgd29yZCBpbiBlYWNoIHNlbnRlbmNlIHJlcXVpcmVzIGRlZmluaW5nIHdoYXQgYSBwYXR0ZXJuIGNvbnN0aXR1dGVzIGEgd29yZC4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIHF1ZXN0aW9uLCBJ4oCZbGwgY29uc2lkZXIgYSB3b3JkIGFueSBjb250aWd1b3VzIHNldCBvZiBsZXR0ZXJzLiBTaW5jZSBgc3RyX2V4dHJhY3QoKWAgd2lsbCBleHRyYWN0IHRoZSBmaXJzdCBtYXRjaCwgaWYgaXQgaXMgcHJvdmlkZWQgYSByZWd1bGFyIGV4cHJlc3Npb24gZm9yIHdvcmRzLCBpdCB3aWxsIHJldHVybiB0aGUgZmlyc3Qgd29yZC4NCg0KYGBge3J9DQpzdHJfZXh0cmFjdChzZW50ZW5jZXMsICJbQS1aQWEtel0rIikgJT4lIGhlYWQoKQ0KYGBgDQoNCkhvd2V2ZXIsIHRoZSB0aGlyZCBzZW50ZW5jZSBiZWdpbnMgd2l0aCDigJxJdOKAmXPigJ0uIFRvIGNhdGNoIHRoaXMsIEnigJlsbCBjaGFuZ2UgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZXF1aXJlIHRoZSBzdHJpbmcgdG8gYmVnaW4gd2l0aCBhIGxldHRlciwgYnV0IGFsbG93IGZvciBhIHN1YnNlcXVlbnQgYXBvc3Ryb3BoZS4NCg0KYGBge3J9DQpzdHJfZXh0cmFjdChzZW50ZW5jZXMsICJbQS1aYS16XVtBLVphLXonXSoiKSAlPiUgaGVhZCgpDQpgYGANCg0KKioyLioqIFRoaXMgcGF0dGVybiBmaW5kcyBhbGwgd29yZHMgZW5kaW5nIGluIGluZy4NCg0KYGBge3J9DQpwYXR0ZXJuIDwtICJcXGJbQS1aYS16XStpbmdcXGIiDQpzZW50ZW5jZXNfd2l0aF9pbmcgPC0gc3RyX2RldGVjdChzZW50ZW5jZXMsIHBhdHRlcm4pDQp1bmlxdWUodW5saXN0KHN0cl9leHRyYWN0X2FsbChzZW50ZW5jZXNbc2VudGVuY2VzX3dpdGhfaW5nXSwgcGF0dGVybikpKSAlPiUNCiAgaGVhZCgpDQpgYGANCg0KKiozLioqIEZpbmRpbmcgYWxsIHBsdXJhbHMgY2Fubm90IGJlIGNvcnJlY3RseSBhY2NvbXBsaXNoZWQgd2l0aCByZWd1bGFyIGV4cHJlc3Npb25zIGFsb25lLiBGaW5kaW5nIHBsdXJhbCB3b3JkcyB3b3VsZCBhdCBsZWFzdCByZXF1aXJlIG1vcnBob2xvZ2ljYWwgaW5mb3JtYXRpb24gYWJvdXQgd29yZHMgaW4gdGhlIGxhbmd1YWdlLiBTZWUgW1dvcmROZXRdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy93b3JkbmV0L2luZGV4Lmh0bWwpIGZvciBhIHJlc291cmNlIHRoYXQgd291bGQgZG8gdGhhdC4gSG93ZXZlciwgaWRlbnRpZnlpbmcgd29yZHMgdGhhdCBlbmQgaW4gYW4g4oCcc+KAnSBhbmQgd2l0aCBtb3JlIHRoYW4gdGhyZWUgY2hhcmFjdGVycywgaW4gb3JkZXIgdG8gcmVtb3ZlIOKAnGFz4oCdLCDigJxpc+KAnSwg4oCcZ2Fz4oCdLCBldGMuLCBpcyBhIHJlYXNvbmFibGUgaGV1cmlzdGljLg0KDQpgYGB7cn0NCnVuaXF1ZSh1bmxpc3Qoc3RyX2V4dHJhY3RfYWxsKHNlbnRlbmNlcywgIlxcYltBLVphLXpdezMsfXNcXGIiKSkpICU+JQ0KICBoZWFkKCkNCmBgYA0K