使用grep匹配不同可能性的string
我想看看,如果在0
和1
的4个字符的string中出现"001"
或"100"
或"000"
。 例如,一个4个字符的string可以像"1100"
或"0010"
或"1001"
或"1111"
。 如何用单个命令匹配string中的许多string?
我知道grep可以用于模式匹配,但是使用grep,我一次只能检查一个string。 我想知道是否可以使用多个string与其他命令或使用grep本身。
是的你可以。 |
在grep
模式中具有与or
相同的含义。 所以你可以使用"001|100|000"
作为你的模式来testing你的模式。 同时, grep
被vector化了,所有这一切都可以一步完成:
x <- c("1100", "0010", "1001", "1111") pattern <- "001|100|000" grep(pattern, x) [1] 1 2 3
这将返回一个索引,其中包含匹配模式的向量(在本例中为前三个)。
有时候有一个逻辑向量可以更方便地告诉你向量中的哪些元素是匹配的。 那么你可以使用grepl
:
grepl(pattern, x) [1] TRUE TRUE TRUE FALSE
有关R ?regex
的帮助,请参见?regex
编辑:为了避免手动创build图案,我们可以使用paste
:
myValues <- c("001", "100", "000") pattern <- paste(myValues, collapse = "|")
这是一个使用stringr
包的解决scheme
require(stringr) mylist = c("1100", "0010", "1001", "1111") str_locate(mylist, "000|001|100")
使用-e参数来添加其他模式:
echo '1100' | grep -e '001' -e '110' -e '101'
您也可以使用data.table
库中的%like%
运算符。
library(data.table) # input x <- c("1100", "0010", "1001", "1111") pattern <- "001|100|000" # check for pattern x %like% pattern > [1] TRUE TRUE TRUE FALSE
如果你想要逻辑向量,那么你应该从stringi
包中检查stri_detect
函数。 在你的情况下,模式是正则expression式,所以使用这个:
stri_detect_regex(x, pattern) ## [1] TRUE TRUE TRUE FALSE
还有一些基准:
require(microbenchmark) test <- stri_paste(stri_rand_strings(100000, 4, "[0-1]")) head(test) ## [1] "0001" "1111" "1101" "1101" "1110" "0110" microbenchmark(stri_detect_regex(test, pattern), grepl(pattern, test)) Unit: milliseconds expr min lq mean median uq max neval stri_detect_regex(test, pattern) 29.67405 30.30656 31.61175 30.93748 33.14948 35.90658 100 grepl(pattern, test) 36.72723 37.71329 40.08595 40.01104 41.57586 48.63421 100
对不起,这是一个额外的答案,但它是太多的评论线。
我只是想提醒一下,通过paste(..., collapse = "|")
可以作为单个匹配模式粘贴在一起的项目数量是有限的 – 见下文。 也许有人可以知道究竟是什么限制? 不得不承认这个数字可能不现实,但是根据要执行的任务,不应该完全排除我们的考虑。
对于大量的项目,循环将需要检查模式的每个项目。
set.seed(0) samplefun <- function(n, x, collapse){ paste(sample(x, n, replace=TRUE), collapse=collapse) } words <- sapply(rpois(10000000, 8) + 1, samplefun, letters, '') text <- sapply(rpois(1000, 5) + 1, samplefun, words, ' ') #since execution takes a while, I have commented out the following lines #result <- grepl(paste(words, collapse = "|"), text) # Error in grepl(pattern, text) : # invalid regular expression # 'wljtpgjqtnw|twiv|jphmer|mcemahvlsjxr|grehqfgldkgfu| # ... #result <- stringi::stri_detect_regex(text, paste(words, collapse = "|")) # Error in stringi::stri_detect_regex(text, paste(words, collapse = "|")) : # Pattern exceeds limits on size or complexity. (U_REGEX_PATTERN_TOO_BIG)