Python 正则表达式:匹配从简单字符串派生的多个模式
我有以下任务: 从30个字符长的模式序列开始(实际上是DNA序列,以免称之为P30),我需要在文本文件中找到所有以精确的P30开头的行(^Agatacag…),然后是30、28和最多10个字符中的最后29个字符。我所需要做的只是删除模式的第一个字符并继续搜索。 为了简单起见,我目前需要精确匹配,但是允许长时间(20-30个字符长的模式)的1个不匹配会更好 我目前的解决方案是创建一个shell文件,每行有一个被截断的模式,grep[1]将其删除。这意味着我正在阅读巨大的、很少GB的文本文件20x,这可能需要一天时间 我可以切换到python,创建一个包含所有必需模式的列表/元组,然后只读取一次文件,而不是每个序列循环20次,使用pypy加快速度Python 正则表达式:匹配从简单字符串派生的多个模式,python,regex,d,fastq,Python,Regex,D,Fastq,我有以下任务: 从30个字符长的模式序列开始(实际上是DNA序列,以免称之为P30),我需要在文本文件中找到所有以精确的P30开头的行(^Agatacag…),然后是30、28和最多10个字符中的最后29个字符。我所需要做的只是删除模式的第一个字符并继续搜索。 为了简单起见,我目前需要精确匹配,但是允许长时间(20-30个字符长的模式)的1个不匹配会更好 我目前的解决方案是创建一个shell文件,每行有一个被截断的模式,grep[1]将其删除。这意味着我正在阅读巨大的、很少GB的文本文件20x,
- 问题1:有没有比这种循环更快的正则表达式李>
- 问题2:通过切换到更快的编译语言来加速它有意义吗?(我试图理解德朗)
^abcde
^bcde
^cde
或者,如果您喜欢将其作为DNA:
^GATACCA
^ATACCA
^TACCA
编辑_2
简单的grep并不能真正解决这个问题。我需要对FASTQ格式的每4行进行后期处理,其中只有第2行匹配。如果我不使用fqgrep,那么我必须:
阅读输入的4行内容-检查第2行(序列)是否以20种模式(P30-P10)中的任何一种开始
-如果我得到匹配,我需要剪切第2行和第4行的前N个字符,其中N代表匹配模式的长度 -在输出/写入文件行打印输出#1-$4,不匹配,不执行任何操作 对于内部解决方案,我可以尝试使用GNU并行将输入文件拆分为4百万个谎言块,并以这种方式加快速度。但是,如果我想让每一个新软件都能被其他人使用,我就要求最终用户安装更复杂的广告 **编辑3** Vyctor中的正则表达式和匹配行的简单示例:
starting P30 regex
^agacatacagagacatacagagacatacag
matching sequence:
^agacatacagagacatacagagacatacagGAGGACCA
P29:
^gacatacagagacatacagagacatacag
matching sequence:
^gacatacagagacatacagagacatacagGACCACCA
P28:
^acatacagagacatacagagacatacag
matching sequence:
^acatacagagacatacagagacatacagGATTACCA
我去掉左边的字符/DNA碱基(或者说DNA中的5素数端),因为这是真实酶降解这些序列的方式。一旦发现正则表达式序列,它本身就不有趣了。所需的输出是正则表达式之后的读取序列。在上面的例子中,它是在超级情况下,然后可以在下一步映射到基因组。
应该强调的是,除了这个玩具示例之外,我在正则表达式模式之后获得了更长的、先验未知的和变化的序列。在现实世界中,我不必处理DNA的大写/小写字符(所有字符都是大写),但我在搜索模式的序列中可能会遇到Ns(=未知DNA碱基)。在一级近似中可以忽略这些,但对于更敏感的算法版本,可能应将其视为简单的不匹配。在理想情况下,不计算给定位置的简单不匹配,而是计算更复杂的惩罚,考虑到以FASTQ格式存储的每个4行长序列记录的第4行中存储的DNA序列质量值:
但这要复杂得多,到目前为止,“只读取与regex完全匹配的数据”方法已经足够好了,并且使后续步骤更容易分析 您可以通过编程方式生成如下所示的正则表达式。
它只是行开始或下一个字符的渐进交替 这将使您能够进行单遍搜索。
您只需获取匹配的字符串长度即可告诉您
你在哪里 注意-使用多行模式
# (?:^|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
如果我理解正确,则您有要匹配的预设:
agacatacag
然后匹配匹配的行:
re:agacatacag
30:Agacatacag Agacatacag
29:AgacatacagAgacatacac
28:Agacataccc
你不需要正则表达式,你只需要找到两行之间的差异,因为它是DNA,我假设字符串abcde
和aebcd
的差异为4,因为所有序列都需要在正确的位置
如果顺序无关紧要,并且您只想搜索至少匹配28个字符的行,那么您可以直接搜索
如果您需要的匹配实际上是以正确的顺序开始的,那么您可以在第一个差异位于点=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
我认为你的问题是很好的结束,因为你不清楚你在问什么。请添加一些示例,说明您试图如何处理“这是源代码,这是预期的输出”。如果您添加当前的
sh
文件,也会有所帮助。也可以考虑这些很棒的答案:只需选择前20个字符匹配:<代码> ^?g?a?c?a?c?a?g?……/代码>我为你张贴了一些更新信息。实际上,当您只需要一个常量表达式时,不需要检查30个单独的正则表达式。例如,在edit_2中,匹配长度减去P30字符的整个长度会告诉您要修剪多少。这是一个简单的减法。这真的很简单。你的例子很好,但我认为
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