提取具有两个以上字符并匹配模式的列表元素

Extract elements of a list with more than two characters and matching a pattern

我正在尝试查找一个列表的索引,其中一个元素与特定模式匹配并且 n 个字符>1,例如:

i = "a"
ll = list(c("a"), c("b", "abc"), c("cc", "b"), c("c", "b"), c("ac", "c"), c("a", "bc"))

我想提取 ll[[2]] 和 ll[[5]]。这种让我走上了正确的道路,但并不完全是因为我只想要包含模式并具有 nchar>1...

的元素
sapply(ll, function(x) sapply(x, function(x) nchar(x)>1 & grep(i, x)))

谢谢!!

ll[sapply(ll, function(x) any(ifelse(nchar(x) > 1, grepl("a", x), FALSE)))]

使用 tidyverse 包的解决方案。

library(purr)
library(stringr)
library(magrittr)

ll %>% map(function(x) x[any(nchar(x) > 1) & str_detect(x,"a")]) %>%
 Filter(length,.)

我们可以使用Filter。这个想法是找到那些具有 a 的元素,对这些元素进行子集化,检查这些元素是否具有 nchar 大于 1,用 any 包装它(如果每个 list 元素)和 Filter 它。

Filter(function(x) any(nchar(x[grep(i, x)])>1), ll)
#[[1]]
#[1] "b"   "abc"

#[[2]]
#[1] "ac" "c" 

Filter(function(x) any(nchar(grep(i, x, value = TRUE))>1), ll)

不使用 nchar 的稍微不同的方法会更多地利用正则表达式。

Has n characters>1

表示可以先有一些字符再有"a"或者"a"再有一些字符。作为正则表达式:"[[:alpha:]]a | a[[:alpha:]]"| 表示 "or".
这导致:

Filter(function(x) any(grepl("[[:alpha:]]a|a[[:alpha:]]", x)), ll)

另一个更通用的选项是使用 lookahaeds (~AND),如下所示:

Filter(function(x) any(grepl("(?=[[:alpha:]]{2,})(?=a)", x, perl=TRUE)), ll)

其中 [[:alpha:]]{2,} 表示至少 2 个字母字符 = A-Za-z a 意味着它需要有一个 a。参见 Regular Expressions: Is there an AND operator?

编辑:

您始终可以使用 pastesprintf "build" 这些正则表达式,如下所示:

i="a"
sprintf("(?=[[:alpha:]]{2,})(?=%s)", i) # Second solution

总的来说是这样的

Filter(function(x) any(grepl(sprintf("(?=[[:alpha:]]{2,})(?=%s)", i), x, perl=TRUE)), ll)