比#34;(cg [agct])|(ag [ag])"更高效的正则表达式

时间:2011-12-15 00:01:16

标签: regex

我需要一个正则表达式匹配以下任何一个:

cgt, cgc, cga, cgg, aga, agg

他们是DNA密码子。我给出的正则表达式(cg[agct])|(ag[ag])是否尽可能高效?它似乎很笨重,我想知道我是否可以使用g作为第二个字符的事实。

1 个答案:

答案 0 :(得分:4)

总结评论:

看来你拥有的东西非常好。

一个建议是将分组更改为非捕获组(或将它们全部删除)。

这样的事情似乎是最佳的:

cg[agct]|ag[ag]

如果你的FAR设置比其他设备更频繁,你可以可能通过将其逐字地添加到交替中来加速(稍微):

cgg|cg[act]|ag[ag]

在内部,大多数正则表达式引擎会将这样的小字符类转换为自己的替换。最大可能是最快地扩展交替,或者在不同的组中,以查看性能影响。

我建议您使用正则表达式引擎来描述所有这三种方法:

cg[agct]|ag[ag]

cga|cgc|cgg|cgt|aga|agg

[ac]g[agct](?<!agt|agc)

最后一个是最接近你的问题的答案,因为它利用了中间需要“g”并使用“负面后瞻”来消除无效集的事实。

要检查的另一件事是,如果只找到[ac]g[agct]的所有实例(包括不需要的“agt”和“agc”),然后用您选择的语言过滤它们将是最快的。


编辑,科学!

以下是各种类型的匹配和失败的图表,以及达成结论所需的步骤数(匹配或不匹配)。

     cg[agct]|ag[ag]   [ac]g[agct](?<!agt|agc)    cga|cgc|cgg|cgt|aga|agg
agg  4                 6                          10                     
agc  4                 8                          10                     

cga  3                 6                          3                      

axa  3                 2                          8                      
cxa  3                 2                          10                      

xxx  2                 1                          6                      

因此,似乎(正如我们猜测的),这些方法具有完全不同的属性。

我对将一切分成交替的预感是错误的。不要使用它。

你应该保证在中间使用“g”,但是对于部分匹配(例如,聚合)和完全匹配(例如cga)需要更长的时间。但是,使用负面的后视版本,丢弃不良结果的速度会轻微

所以,为了弥补最坏的情况,(8次检查对比3 = delta -5),我们必须看到至少5个失败的角色位置。 (2次检查对比3 =增量1或1检查对比2 =增量1)

我想,如果您预计在找到的每场比赛的5个位置都会失败,那么您应该使用负面的lookbehind版本。


编辑2,略微更好的版本

看看正则表达式如何评估每个匹配,我们可以制作一个更好的版本,让大约一半的匹配“快速跟踪”,并且还会减少匹配失败时检查的字符数。 / p>

       [ca]g(?:[ag]|(?<!ag)[ct])
agg    4
agc    7

cga    4

axa    2
cxa    2

xxx    1

这会使所有正匹配时间减少一次或两次比较。

基于此,如果您希望为每场比赛检查4个或更多位置,我建议您使用[ca]g(?:[ag]|(?<!ag)[ct])