所以,我正在用一种酶来消化一个蛋白质序列(为了引起你的好奇心,我称之为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都支持零宽度的先行断言。我的正则表达式做错了什么?
发布于 2011-05-19 10:40:08
支持这一点的最简单方法是在零宽度前视中拆分:
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的简单实现可能会陷入无限循环,重复匹配第一个字符之前的指针。看起来,一旦出现匹配而没有推进指针,算法就会强制将指针前进一个字符。这解释了您的案例中的结果:
发布于 2011-05-19 07:41:54
基本上,你想在每个B或D之前剪断你的弦?
"...".split(/(?=[BD])/)为您提供
["MTM", "DKPSQY", "DKIEAELQ", "DICN", "DVLELL", "DSKG", "DYFRYLSEVASG", "DN"]https://stackoverflow.com/questions/6052211
复制相似问题