我正在尝试解析一组字符串。
我需要找出样本中是否检测到“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)
匹配一个空位置(空字符串),后跟bcl2
或bcl-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"