正则表达式蛋白质消化

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

 (\w*?)(?=[BD])|(.*\b) 

前提条件(.*\b)存在以捕获序列的结尾。 对于:

 MTMDKPSQYDKIEAELQDICNDVLELLDSKGDYFRYLSEVASGDN 

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

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

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

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

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

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

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

 s = "abcd" p s.scan // # Match any position, without advancing #=> ["", "", "", "", ""] p s.scan /(?=.)/ # Anywhere that is followed by a character, without advancing #=> ["", "", "", ""] 

String#scan可能会陷入无限循环,在第一个字符之前重复匹配指针。 似乎一旦匹配发生而没有推进指针,算法强制将指针前进一个字符。 这解释了您案例中的结果:

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

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

 "...".split(/(?=[BD])/) 

给你

 ["MTM", "DKPSQY", "DKIEAELQ", "DICN", "DVLELL", "DSKG", "DYFRYLSEVASG", "DN"]