【问题标题】:Pattern matching in R if string NOT followed but another string如果没有跟随字符串但另一个字符串,则在 R 中进行模式匹配
【发布时间】:2021-10-22 09:24:31
【问题描述】:

我正在尝试使用 stringr 包中的 str_detect 在 R 中匹配以下内容。

我想检测给定的字符串是否在'and'或'&'之后或之前。例如,在:

string_1<-"A and B"
string_2<-"A B"
string_3<-"B and A"
string_4<-"A B and C"

我希望 str_detect(string_X) 对于 string_1、string_3 和 string_4 为 FALSE,但对于 string_2 为 TRUE。

我试过了:


str_detect(string_X,paste0(".*(?<!and |& )","A"))==TRUE & str_detect(string_X,paste0(".*","A","(?! and| &).*"))==TRUE)


我使用 paste0 是因为我想在不同的字符串上运行它。这适用于除 4 之外的所有情况。我是正则表达式的新手,而且看起来也不是很优雅。有没有更通用的解决方案?

谢谢。

【问题讨论】:

    标签: r regex string pattern-matching regex-lookarounds


    【解决方案1】:

    首先让我们将你的四个字符串组合成一个向量:

    strings <- c(string_1, string_2, string_3, string_4)
    

    现在使用

    library(stringr)
    
    str_detect(strings, "(A|B)(?=\\s(and|&))", negate = TRUE)
    

    我们查找“A”或“B”后跟“and”或“&”。所以这会返回

    #> [1] FALSE  TRUE FALSE FALSE
    

    你可以把它包装成一个函数:

    detector <- function(letters, strings) {
      pattern <- paste0("(", paste0(letters, collapse = "|"), ")(?=\\s(and|&))")
      str_detect(strings, pattern, negate = TRUE)
    }
    
    detector(c("A", "B"), strings)
    #> [1] FALSE  TRUE FALSE FALSE
    
    detector(c("A"), strings)
    #> [1] FALSE  TRUE  TRUE  TRUE
    
    detector(c("B"), strings)
    #> [1]  TRUE  TRUE FALSE FALSE
    
    detector(c("C"), strings)
    #> [1] TRUE TRUE TRUE TRUE
    

    【讨论】:

      【解决方案2】:

      您可以使用积极的前瞻断言来确保不存在AB,后跟and&amp;,也不按其他顺序。

      ^(?!.*[AB] (?:and|&))(?!.*(?:and|&) [AB])
      
      • ^ 字符串开始
      • (?!.*[AB] (?:and|&amp;)) 断言字符串不包含 AB 后跟 and 或 &
      • (?!.*(?:and|&amp;) [AB]) 断言字符串不包含 and 或 & 后跟 A 或 B

      Regex demo | R demo

      library(stringr)
      
      string_1<-"A and B"
      string_2<-"A B"
      string_3<-"B and A"
      string_4<-"A B and C"
      string_5<-"& B"
      
      strings <- c(string_1, string_2, string_3, string_4, string_5)
      
      str_detect(strings, "^(?!.*[AB] (?:and|&))(?!.*(?:and|&) [AB])")
      

      输出

      [1] FALSE  TRUE FALSE FALSE FALSE
      

      【讨论】:

        猜你喜欢
        • 2021-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-11
        • 2021-10-22
        • 1970-01-01
        相关资源
        最近更新 更多