正则表达式蛋白质消化

Rya*_*nmt 8 ruby regex bioinformatics

所以,我正在用酶(为了你的好奇心,Asp-N)消化蛋白质序列,它在单字母编码序列中由B或D编码的蛋白质之前切割.我的实际分析String#scan用于捕获.我想弄清楚为什么以下正则表达式不能正确消化它...

(\w*?)(?=[BD])|(.*\b)
Run Code Online (Sandbox Code Playgroud)

(.*\b)存在先行词以捕获序列的结尾.对于:

MTMDKPSQYDKIEAELQDICNDVLELLDSKGDYFRYLSEVASGDN
Run Code Online (Sandbox Code Playgroud)

这应该给出类似的东西:[MTM, DKPSQY, DKIEAELQ, DICN, DVLELL, DSKG, ... ]但是错过序列中的每个D.

我一直在使用http://www.rubular.com进行故障排除,运行在1.8.7上虽然我也在1.9.2上测试了这个REGEX但无济于事.据我所知,在两个版本的ruby中都支持零宽度前瞻断言.我的正则表达式做错了什么?

Tho*_*ens 9

基本上,你想在每个B或D之前剪掉你的字符串吗?

"...".split(/(?=[BD])/)
Run Code Online (Sandbox Code Playgroud)

给你

["MTM", "DKPSQY", "DKIEAELQ", "DICN", "DVLELL", "DSKG", "DYFRYLSEVASG", "DN"]
Run Code Online (Sandbox Code Playgroud)


Phr*_*ogz 4

支持这一点的最简单方法是在零宽度前瞻上进行拆分:

s = "MTMDKPSQYDKIEAELQDICNDVLELLDSKG"
p s.split /(?=[BD])/
#=> ["MTM", "DKPSQY", "DKIEAELQ", "DICN", "DVLELL", "DSKG"]
Run Code Online (Sandbox Code Playgroud)

为了了解您的解决方案出了什么问题,让我们首先看看您的正则表达式与有效的正则表达式:

p s.scan(/.*?(?=[BD]|$)/)
#=> ["MTM", "", "KPSQY", "", "KIEAELQ", "", "ICN", "", "VLELL", "", "SKG", ""]

p s.scan(/.+?(?=[BD]|$)/)
#=> ["MTM", "DKPSQY", "DKIEAELQ", "DICN", "DVLELL", "DSKG"]
Run Code Online (Sandbox Code Playgroud)

问题是,如果您可以捕获零个字符并且仍然匹配零宽度前瞻,那么您无需前进扫描指针即可成功。让我们看一个更简单但相似的测试用例:

s = "abcd"
p s.scan //      # Match any position, without advancing
#=> ["", "", "", "", ""]

p s.scan /(?=.)/ # Anywhere that is followed by a character, without advancing
#=> ["", "", "", ""]
Run Code Online (Sandbox Code Playgroud)

幼稚的实现String#scan可能会陷入无限循环,反复匹配第一个字符之前的指针。看起来,一旦发生匹配而没有使指针前进,算法就会强制将指针前进一个字符。这解释了您的案例的结果:

  1. 首先它匹配 B 或 D 之前的所有字符,
  2. 然后它匹配 B 或 D 之前的零宽度位置,而不移动字符指针,
  3. 结果,算法将指针移过 B 或 D,然后继续。