提取可能字符列表左侧的所有字符

Extract all characters to the left of a list of possible characters

我在数据框中有一系列字符串,如下所示:

item_time<-c("pink dress july noon", "shirt early september morning", "purple dress 
april", "tall purple shoes february")

我想提取可能字符列表左侧的所有字符,如下所示:

time<-c("january", "january night", "february","march","april","may", "may 
morning", "june","july", "july noon","august","september","early september morning", 
"october","november","december")

我想要的结果是这样的:

[1] pink dress
[2] shirt
[3] purple dress
[4] tall purple shoes

我无法用空格分隔它们,因为时间和项目列表中的单词数量不同。我也没有将它们分开的符号。我觉得应该有一种非常简单而优雅的方法来解决这个问题,但我想不通。

我们可以在 Base R:

中使用 strsplit
sapply(strsplit(item_time, split=paste0("\s", time, collapse="|")), `[`, 1)
# [1] "pink dress"        "shirt"             "purple dress"      "tall purple shoes"

备注:

我首先折叠 time 向量并用 | 分隔每个项,然后用它来拆分 item_timestrsplit。由于 strsplit 中的 split 参数接受正则表达式,它会将 | 解释为 OR 运算符,只要它看到 time 中的一项,它就会有效地拆分 item_timesapply(...,[, 1) 然后查看列表中的每个元素并提取第一个元素,这将是拆分后最左边的字符串。

实现此目的的一种方法是将可能字符的向量转换为正则表达式模式,并使用它来提取正确的字符串,如下所示。

这是通过使用 | 分隔可能字符的所有选项,然后将它们放在前瞻 (?= ) 中来实现的。这会尝试匹配选项列表之前的模式。然后我们只需添加 ^.* 来收集时间列表之前的整个字符串,从头开始。

请注意,如果 time 中的任何选项有特殊字符,这将失败,如果 time 中的选项在item_time.

条目
item_time <- c(
  "pink dress july noon", "shirt september morning",
  "purple dress april", "tall purple shoes february"
)

time <- c(
  "january", "january night", "february", "march", "april", "may",
  "may morning", "june", "july", "july noon", "august", "september",
  "september morning", "october", "november", "december"
)

library(stringr)
pattern <- time %>%
  str_c(collapse = "|") %>%
  str_c("^.*(?= (", ., "))")

item_time %>%
  str_extract(pattern)
#> [1] "pink dress"        "shirt"             "purple dress"     
#> [4] "tall purple shoes"

reprex package (v0.2.0) 创建于 2018-08-13。

您可以使用 sub,因为它是矢量化的

sub(paste0("\s*",time,".*",collapse="|"),"",item_time)
[1] "pink dress"        "shirt"             "purple dress"      "tall purple shoes"