简单近似——由至少一个非空格字符组成的序列:
noun <- "(a|the) ([^ ]+)" has_noun <- sentences %>% str_subset(noun) %>% head(10) has_noun %>% str_extract(noun) #> [1] "the smooth" "the sheet" "the depth" "a chicken" #> [5] "the parked" "the sun" "the huge" "the ball" #> [9] "the woman" "a helps"
str_extract() 给出完整匹配;str_match() 则给出每个单独的组成部分。它返回的不是字符向量,而是一个矩阵,第一列是完整匹配,后面每列对应一个分组:
has_noun %>% str_match(noun) #> [,1] [,2] [,3] #> [1,] "the smooth" "the" "smooth" #> [2,] "the sheet" "the" "sheet" #> [3,] "the depth" "the" "depth" #> [4,] "a chicken" "a" "chicken" #> [5,] "the parked" "the" "parked" #> [6,] "the sun" "the" "sun" #> [7,] "the huge" "the" "huge" #> [8,] "the ball" "the" "ball" #> [9,] "the woman" "the" "woman" #> [10,] "a helps" "a" "helps"
(不出所料,我们检测名词的启发式方法效果很差,还会把 smooth 和 parked 这样的形容词也匹配进来。)
如果你的数据存储在 tibble 中,使用 tidyr::extract() 通常更方便。它的作用类似于 str_match(),但要求你为匹配结果命名,这些结果随后会被放入新的列中:
tibble(sentence = sentences) %>% tidyr::extract( sentence, c("article", "noun"), "(a|the) ([^ ]+)", remove = FALSE ) #> # 一个 tibble:720 行 × 3 列 #> sentence article noun #> *