正则表达式蛋白质消化
所以,我正在用酶(为了你的好奇心,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
可能会陷入无限循环,在第一个字符之前重复匹配指针。 似乎一旦匹配发生而没有推进指针,算法强制将指针前进一个字符。 这解释了您案例中的结果:
- 首先它匹配所有角色直到B或D,
- 然后它匹配B或D之前的零宽度位置,而不移动字符指针,
- 结果,算法将指针移过B或D,然后继续。
基本上,你想在每个B或D之前剪掉你的字符串吗?
"...".split(/(?=[BD])/)
给你
["MTM", "DKPSQY", "DKIEAELQ", "DICN", "DVLELL", "DSKG", "DYFRYLSEVASG", "DN"]