我正在尝试解析一组字符串。 我需要弄清楚是否' bcl-2'在样品中检测到。 例如:"在45%的患者中检测到bl-2"。 然而,某些可能的变化具有挑战性:
1。" bcl-2检测到45%bcl-6 未检测到"
2." bcl-2 不检测到bcl-6被检测到45%"
3." 没有 bcl-2 bcl-6的证据在45%"
所以我试图定义正则表达式代码:
1.预测' bcl-2'
然后,从那一点开始前瞻,以便检测到'
3.然后在' bcl-2'之间看后面并且'检测到'确保没有'没有'
4.如果可能,请在背后' bcl-2'确保没有证据表明' (虽然我可以单独处理这个条件)
我尝试了以下不起作用的代码。具体来说,它并不是落后的,所以我猜测有一些我缺失的背后隐藏的东西。
此正则表达式适用于" bcl-2 未检测到"但失败的" bcl-2被检出45%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)
我试图理解lookbehind的逻辑。关于最后一行代码 - &gt;我认为(?= bcl-?2)向前看直到字符串中以&#39; bcl-2&#39;开头的点。然后,我认为(?=。*检测到)向前看,直到字符串中检测到的位置为止。开始。然后我觉得lookbehind开始从那个位置向后看,而不是&#39;。这当然是错误的...所以我错过了关于环视逻辑
的内容BTW我一直在使用的一个很棒的网站,试图解决这个问题 https://www.regular-expressions.info/recurse.html
答案 0 :(得分:2)
Lookarounds是零宽度断言,这意味着当模式匹配时,正则表达式索引不会移动(匹配的字符不会添加到匹配值中,并且连续的外观都会从同一位置开始进行模式检查)。因此,(?=bcl-?2)(?!.*not)(?=.*detected)
匹配一个空的位置(空字符串),后跟bcl2
或bcl-2
,除了换行符之外的任何0 +字符之后没有not
子字符串,除了换行符之外的任何0+字符后面跟着detected
。在输入字符串中的每个位置都尝试此模式,因为没有锚点。这种模式很难做到你所需要的。
这是一个可能的解决方案:
\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"