我正在尝试解析一组字符串。
我需要找出样本中是否检测到“bcl-2”。
例如:“在45%的患者中检测到bl-2”。
但是,可能存在某些变化,这些变化具有挑战性:

1.“在45%的bcl-6中检测到bcl-2,但未检测到
2.“bcl-2被检测为而不是未检测到bcl-6的检测率为45%”
3.“在45%的位置未检测到bcl-2 bcl-6的没有证据”

所以我试图定义将要的正则表达式代码:
1.展望“bcl-2”
2.然后,从该点向前寻找“检测到”
3.然后在“bcl-2”和“检测到”之间的
之后查看,以确保没有“not”。
4.如果可能,请在
'bcl-2'后面查找,以确保没有“证据”(尽管我可以单独处理这种情况)

我尝试了以下无效的代码。具体来说,它不在后面,所以我想我在后面看起来有些内在的东西。

此正则表达式适用于“未检测到bcl-2 而不检测到”,但是对于“在45%的bcl-6中检测到bcl-2却未检测到
”而失败。

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”的位置开始。然后我以为后视开始从该位置向后看“不是”。这当然是错误的...所以我对环视逻辑缺少什么

顺便说一句,我一直在尝试一个很棒的网站
https://www.regular-expressions.info/recurse.html

最佳答案

环视是零宽度的断言,这意味着匹配模式时正则表达式索引不会移动(匹配的字符不会添加到匹配值中,并且连续的环视都从同一位置开始其模式检查)。因此,(?=bcl-?2)(?!.*not)(?=.*detected)匹配一个空位置(空字符串),后跟bcl2bcl-2,在除换行符以外的任何0+字符之后没有not子字符串,并且在跟着除换行符以外的任何0+字符之后跟随detected字符因为没有 anchor ,所以在输入字符串的每个位置都尝试此模式。这种模式几乎无法满足您的需求。

这是一个可能的解决方案:

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

参见regex demo:
  • \b-单词边界
  • bcl-2-一个bcl-2子字符串
  • \b-单词边界
  • (?:(?!\bbcl-\d|\bnot\b).)*?-(a tempered greedy token)除换行符以外的任何0+(但应尽可能少)的字符,它们不以以下两个序列开头:
  • \bbcl-\d-一个令人担忧的边界,后跟bcl-和一个数字
  • |-或
  • \bnot\b-整个单词not
  • \bdetected\b-整个单词detected

  • 请参见下面的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"
    

    10-01 10:33