【问题标题】:Find matching patterns from list of patterns using grepl使用 grepl 从模式列表中查找匹配模式
【发布时间】:2023-04-03 23:11:01
【问题描述】:

我使用 grepl 来检查字符串是否包含一组模式中的任何模式(我使用 '|' 分隔模式)。反向搜索没有帮助。如何识别匹配的模式集?

附加信息:这可以通过编写一个循环来解决,但它非常耗时,因为我的集合有 > 100,000 个字符串。可以优化吗?

例如:设字符串为a <- "Hello"

pattern <- c("ll", "lo", "hl")

pattern1 <- paste(pattern, collapse="|") # "ll|lo|hl"

grepl(a, pattern=pattern1) # returns TRUE

grepl(pattern, pattern=a) # returns FALSE 'n' times - n is 3 here

【问题讨论】:

  • 如果我能获得每个元素的所有匹配项,那就太好了。目前我正在迭代所有元素('a')
  • 嗯,我不知道在这种情况下是否有创建矩阵的函数,我需要阅读文档,确实很有趣!
  • 您的答案比蛮力优化得多。比较:所用时间间隔为 15 分钟。蛮力:346 次迭代 str_detect:87000+ 次迭代

标签: regex r string grepl


【解决方案1】:

您正在从包stringr 中寻找str_detect

library(stringr)

str_detect(a, pattern)
#[1]  TRUE  TRUE FALSE

如果您有多个字符串,例如a = c('hello','hola','plouf'),您可以这样做:

lapply(a, function(u) pattern[str_detect(u, pattern)])

【讨论】:

    【解决方案2】:

    您还可以使用带有前瞻表达式(?=) 的基本 R,因为模式重叠。使用gregexpr,您可以将每个分组模式的匹配位置提取为矩阵。

    ## changed your string so the second pattern matches twice
    a <- "Hellolo"
    pattern <- c("ll", "lo", "hl")
    pattern1 <- sprintf("(?=(%s))", paste(pattern, collapse=")|(")) #  "(?=(ll)|(lo)|(hl))"
    
    attr(gregexpr(pattern1, a, perl=T)[[1]], "capture.start")
    # [1,] 3 0 0
    # [2,] 0 4 0
    # [3,] 0 6 0
    

    矩阵的每一列对应于模式,所以模式2匹配测试字符串中的位置4和6,模式1匹配位置3,依此类推。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 2017-06-11
      • 1970-01-01
      • 2021-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多