我有以下任务: 从30个字符长的模式序列开始(它实际上是DNA序列,以免称之为P30)我需要在文本文件中找到所有以#30开头的行(^ agacatacag ...),然后是30个最后30个字符,28和最多10个字符。我需要做的就是删除模式的第一个字符并继续搜索。 为简单起见,我目前需要精确匹配,但允许更长时间(20-30个字符长的模式)的1个不匹配会更好。
我当前的,相当慢的解决方案是创建一个每行有一个截断模式的shell文件,然后grep [1]。这意味着我正在阅读巨大的,少量的GB文本文件20x,这可能需要一天+。
我可以切换到python,创建一个包含所有必需模式的列表/元组,然后只读取一次文件,每个序列循环20次,使用pypy加快速度。
[1]因为它是DNA序列而且要搜索的输入是FASTQ格式我使用的是fqgrep:https://github.com/indraniel/fqgrep 使用tre库:https://github.com/laurikari/tre/
edit_1 变化的例子(缩短模式)。只显示了前几步/更短的模式:
^abcde
^bcde
^cde
或者如果您更喜欢它作为DNA:
^GATACCA
^ATACCA
^TACCA
edit_2 简单的grep并没有真正削减它。我需要对每行只有第2行匹配的4行FASTQ格式进行后处理。如果我不使用fqgrep,那么我必须:
读取4行输入
- 检查第2行(序列)是否以20种模式(P30-P10)中的任何一种开始
- 如果我得到了匹配,我需要删除第2行和第4行的前N个字符,其中N代表匹配模式的长度
- 打印输出/写入文件行#1- $ 4无匹配无效
对于内部解决方案,我可以尝试使用GNU并行分割输入文件,例如4M的谎言块,并以这种方式加快速度。但是,如果我想让其他人使用每个新软件,我要求最终用户安装广告,这是一个额外的复杂程度。
**编辑3 ** 来自Vyctor的正则表达式和匹配行的简单示例:
starting P30 regex
^agacatacagagacatacagagacatacag
matching sequence:
^agacatacagagacatacagagacatacagGAGGACCA
P29:
^gacatacagagacatacagagacatacag
matching sequence:
^gacatacagagacatacagagacatacagGACCACCA
P28:
^acatacagagacatacagagacatacag
matching sequence:
^acatacagagacatacagagacatacagGATTACCA
我从左侧移除了字符/ DNA碱基(或DNA中的5-prime末端),因为这是这些序列被真实酶降解的方式。一旦找到正则表达式序列本身就没有意义。所需的输出是正则表达式之后的读取序列。在上面的例子中,它在UPERCASE中,然后可以在下一步中映射到基因组。 应该强调的是,除了这个玩具示例之外,我正在变得更长,在正则表达式之后的先验未知和变化的序列。在现实世界中,我不必处理DNA的大小写字符(一切都是大写的),但我可能会在我搜索模式的序列中遇到Ns(=未知的DNA碱基)。这些可以在第一次近似中被忽略,但是对于更敏感的算法版本,可能应该以简单的不匹配来处理。在理想情况下,不考虑给定位置的简单错配,而是计算更复杂的罚分,同时考虑以FASTQ格式存储的每4行长序列记录的第4行中存储的DNA序列质量值:http://en.wikipedia.org/wiki/FASTQ_format#Quality
但这种方式更为复杂,到目前为止,该方法仅采用与正则表达式完全匹配的读取方式。足够好,使后续步骤更容易分析。
答案 0 :(得分:2)
您可以通过编程方式生成正则表达式,如下所示 它只是行开始或下一个字符的渐进式交替。
这将使您能够进行单次搜索 你所要做的就是获得比赛的字符串长度告诉你 你在哪里。
注意 - 使用多线模式。
# (?:^|a)(?:^|g)(?:^|a)(?:^|c)(?:^|a)(?:^|t)(?:^|a)(?:^|c)(?:^|a)(?:^|g)(?!^)0123456789
(?: ^ | a ) # P30
(?: ^ | g ) # P29
(?: ^ | a ) # P28
(?: ^ | c ) # P27
(?: ^ | a ) # P26
(?: ^ | t ) # P25
(?: ^ | a ) # P24
(?: ^ | c ) # P23
(?: ^ | a ) # P22
(?: ^ | g ) # P21
# ..
# P11
(?! ^) # Not beginning of line
0123456789 # P10 - P1
例如,匹配这些:
agacatacag0123456789
cag0123456789
gacatacag0123456789
acatacag0123456789
acag0123456789
catacag0123456789
catacag0123456789
0123456789
atacag0123456789
tacag0123456789
ag0123456789
g0123456789
但不是这些:
agaatacag0123456789
ca0123456789
gacataca0123456789
acaacag0123456789
acg0123456789
cataca0123456789
caacag0123456789
123456789
atacg0123456789
tcag0123456789
ag012456789
g012356789
更新
这是一个图示,单个正则表达式可以替换所有30 真的不需要30个独立的正则表达式,你只需要1个常量正则表达式 在此示例中,群集组将替换为捕获组,以便您可以查看它正在执行的操作。
# (^|G)(^|A)(^|T)(^|A)(^|C)(^|C)(?!^)A
( ^ | G ) # (1)
( ^ | A ) # (2)
( ^ | T ) # (3)
( ^ | A ) # (4)
( ^ | C ) # (5)
( ^ | C ) # (6)
(?! ^ ) # Not beginning of line
A
输入,6行:
GATACCA
ATACCA
TACCA
ACCA
CCA
CA
输出:
** Grp 0 - ( pos 0 , len 7 )
GATACCA
** Grp 1 - ( pos 0 , len 1 )
G
** Grp 2 - ( pos 1 , len 1 )
A
** Grp 3 - ( pos 2 , len 1 )
T
** Grp 4 - ( pos 3 , len 1 )
A
** Grp 5 - ( pos 4 , len 1 )
C
** Grp 6 - ( pos 5 , len 1 )
C
------------------------------
** Grp 0 - ( pos 9 , len 6 )
ATACCA
** Grp 1 - ( pos 9 , len 0 ) EMPTY
** Grp 2 - ( pos 9 , len 1 )
A
** Grp 3 - ( pos 10 , len 1 )
T
** Grp 4 - ( pos 11 , len 1 )
A
** Grp 5 - ( pos 12 , len 1 )
C
** Grp 6 - ( pos 13 , len 1 )
C
------------------------------
** Grp 0 - ( pos 17 , len 5 )
TACCA
** Grp 1 - ( pos 17 , len 0 ) EMPTY
** Grp 2 - ( pos 17 , len 0 ) EMPTY
** Grp 3 - ( pos 17 , len 1 )
T
** Grp 4 - ( pos 18 , len 1 )
A
** Grp 5 - ( pos 19 , len 1 )
C
** Grp 6 - ( pos 20 , len 1 )
C
------------------------------
** Grp 0 - ( pos 24 , len 4 )
ACCA
** Grp 1 - ( pos 24 , len 0 ) EMPTY
** Grp 2 - ( pos 24 , len 0 ) EMPTY
** Grp 3 - ( pos 24 , len 0 ) EMPTY
** Grp 4 - ( pos 24 , len 1 )
A
** Grp 5 - ( pos 25 , len 1 )
C
** Grp 6 - ( pos 26 , len 1 )
C
------------------------------
** Grp 0 - ( pos 30 , len 3 )
CCA
** Grp 1 - ( pos 30 , len 0 ) EMPTY
** Grp 2 - ( pos 30 , len 0 ) EMPTY
** Grp 3 - ( pos 30 , len 0 ) EMPTY
** Grp 4 - ( pos 30 , len 0 ) EMPTY
** Grp 5 - ( pos 30 , len 1 )
C
** Grp 6 - ( pos 31 , len 1 )
C
------------------------------
** Grp 0 - ( pos 35 , len 2 )
CA
** Grp 1 - ( pos 35 , len 0 ) EMPTY
** Grp 2 - ( pos 35 , len 0 ) EMPTY
** Grp 3 - ( pos 35 , len 0 ) EMPTY
** Grp 4 - ( pos 35 , len 0 ) EMPTY
** Grp 5 - ( pos 35 , len 0 ) EMPTY
** Grp 6 - ( pos 35 , len 1 )
C
答案 1 :(得分:2)
如果我理解正确您已预设您想要匹配:
agacatacagagacatacagagacatacag
然后匹配匹配的行:
re: agacatacagagacatacagagacatacag
30: agacatacagagacatacagagacatacag
29: agacatacagagacatacagagacatacac
28: agacatacagagacatacagagacataccc
你真的不需要regexp,你只需要找到两行之间的区别,因为它是DNA我假设字符串abcde
和aebcd
有4的差异,因为所有序列都需要在适当的地方。
如果订单无关紧要,并且您只想搜索至少匹配28个字符的行,则只需count differences in the strings。
reg = 'agacatacagagacatacagagacatacag'
for row in file:
letters = diff_letters(reg, row.strip())
if letters == 30: # complete match
elif letters == 29: # one different character
# so on
如果您需要实际以正确顺序开头的匹配,则可以get points of difference between strings,如果第一个差异在点>=28
reg = 'agacatacagagacatacagagacatacag'
for row in file:
diffs = list(i for i,(a1,a2) in enumerate(zip(s1,s2)) if a1!=a2)
if not len(diffs):
difference = len(reg)
else:
difference = diffs[0]
if difference == 30: # First difference is at last offset