代码之家  ›  专栏  ›  技术社区  ›  user2387584

在R中向前看,以按顺序识别单词模式

  •  3
  • user2387584  · 技术社区  · 8 年前

    我试图解析一组字符串。 我需要找出样本中是否检测到“bcl-2”。 例如:“45%的患者检测到bl-2”。

    1.“bcl-2在45%的患者中检测到,bcl-6在45%的患者中检测到
    2.“bcl-2是 45%的患者检测到bcl-6。”
    3. " 45%的患者检测到bcl-2和bcl-6。”

    所以我试图定义正则表达式代码,它将:

    1、“bcl-2”的展望
    2.然后,从该点向前看“检测到”
    3.然后看 在…的后面
    4 在…的后面 “bcl-2”以确保“没有证据”(尽管我可以单独处理这种情况)

    这个正则表达式适用于“bcl-2 was” 在45%的患者中检测到bcl-2,但未检测到bcl-6 检测到“

    y="bcl-2 was detected in 45% bcl-6 was not detected"
    grepl("(?=bcl-?2)(?!.*not)(?=.*detected)",y, ignore.case = T,perl=T)  
    

    所以我认为这会起作用,但它没有:

    grepl("(?=bcl-?2)(?=.*detected)(?<!not)",y, ignore.case = T,perl=T)
    

    我正在努力理解落后的逻辑。关于最后一行代码->我认为(?=bcl-2)向前看,直到字符串中以“bcl-2”开头的点。然后,我认为(?=.*detected)向前看,直到字符串中“detected”开始的位置。然后我想lookbehind开始从那个位置向后看“not”。这当然是错误的。。。那么,我遗漏了什么环视逻辑呢

    https://www.regular-expressions.info/recurse.html

    1 回复  |  直到 8 年前
        1
  •  2
  •   Wiktor Stribiżew    8 年前

    Lookarounds是零宽度断言,这意味着当模式匹配时正则表达式索引没有移动(匹配的字符没有添加到匹配值,连续的Lookarounds都从同一位置开始其模式检查)。所以 (?=bcl-?2)(?!.*not)(?=.*detected) 匹配后跟的空位置(空字符串) bcl2 bcl-2 not 除换行符以外的任何0+字符后的子字符串,后面跟 detected 在除换行符以外的任何0+字符之后。由于没有锚,因此在输入字符串中的每个位置都会尝试此模式。这种模式很难满足你的需要。

    以下是一个可能的解决方案:

    \bbcl-2\b(?:(?!\bbcl-\d|\bnot\b).)*?\bdetected\b
    

    请参阅 regex demo

    • \b -单词边界
    • bcl-2 -a bcl-2
    • \b -单词边界
    • (?:(?!\bbcl-\d|\bnot\b).)*? -(a) tempered greedy token )任何0+(但尽可能少)字符,而不是不启动以下两个序列的换行符:
      • \bbcl-\d bcl- 和一个数字
      • | -或
      • \bnot\b -一个完整的词
    • \bdetected\b -一个完整的词 检测

    查看 R demo 如下:

    x <- c("bcl-2 was detected in 45% bcl-6 was not detected", 
    "bcl-2 was not detected bcl-6 was detected in 45%",
    "no evidendce of bcl-2 bcl-6 was detected in 45%")
    grep("\\bbcl-2\\b(?:(?!\\bbcl-\\d|\\bnot\\b).)*?\\bdetected\\b", x, perl=TRUE, value=TRUE)
    ## => [1] "bcl-2 was detected in 45% bcl-6 was not detected"