如何捕捉一组最长的序列
How to catch the longest sequence of a group
任务是找到一组最长的序列
例如,给定 DNA 序列:"AGATCAGATCTTTTTTCTAATGTCTAGGATATATCAGATCAGATCAGATCAGATCAGATC"
它出现了 7 次 AGATC。 (AGATC)
匹配所有匹配项。
是否可以编写一个只捕获最长序列的正则表达式,即给定文本中的 AGATCAGATCAGATCAGATCAGATC
?
如果仅使用正则表达式这是不可能的,我如何遍历 python 中的每个序列(即第一个序列是 AGATCAGATC
、第二个 - AGATCAGATCAGATCAGATCAGATC
等等)?
使用:
import re
sequence = "AGATCAGATCTTTTTTCTAATGTCTAGGATATATCAGATCAGATCAGATCAGATCAGATC"
matches = re.findall(r'(?:AGATC)+', sequence)
# To find the longest subsequence
longest = max(matches, key=len)
解释:
非捕获组(?:AGATC)+
+
量词——匹配一次到无限次,尽可能多。
AGATC
按字面匹配字符 AGATC(区分大小写)
结果:
# print(matches)
['AGATCAGATC', 'AGATCAGATCAGATCAGATCAGATC']
# print(longest)
'AGATCAGATCAGATCAGATCAGATC'
您可以测试正则表达式 here
。
使用re.finditer()
遍历所有匹配项。然后使用 max()
和一个键函数来找到最长的。让它成为一个函数,这样你就可以使用不同的组。
import re
def find_longest(sequence, group):
# build pattern
pattern = fr"(?:{group})+"
# iterate over all matches
matches = (match[0] for match in re.finditer(pattern, sequence))
# find the longest
return max(matches, key=len)
seq = "AGATCAGATCTTTTTTCTAATGTCTAGGATATATCAGATCAGATCAGATCAGATCAGATC"
find_longest(seq, "AGATC")
中心问题是,“是否可以编写一个只捕获最长序列的正则表达式?”答案是肯定的:
import re
s = 'AGATC_AGATCAGATC_AGATCAGATCAGATC_AGATC_AGATCAGATC'
m = re.search(r'((?:AGATC)+)(?!.*)', s)
print m.group() if m else ''
#=> "AGATCAGATCAGATC"
Regex demo<¯\(ツ)/¯>Python demo
Python 的正则表达式引擎执行以下操作。
( begin capture group 1
(?:AGATC) match 'AGATC' in a non-capture group
+ execute the non-capture group 1+ times
) end capture group 1
(?! begin a negative lookahead
.* match 0+ characters
match the content of capture group 1
) end the negative lookahead
对于上面的字符串 s
,AGATC
将首先被匹配,但否定前瞻会发现 AGATC
作为 AGATCAGATC
的第一部分,因此暂定匹配会被拒绝。然后 AGATCAGATC
将被匹配,但否定前瞻会发现 AGATCAGATC
作为 AGATCAGATCAGATC
的第一部分,因此临时匹配也将被拒绝。接下来,AGATCAGATCAGATC
将被匹配并接受,因为否定先行不会在字符串后面找到该匹配项。 (re.findall
与 re.search
不同,它还会匹配字符串末尾的 AGATCAGATC
。)
如果使用了 re.findall
,最长的匹配项之后可能会有多个匹配项(请参阅正则表达式演示 link 处的最后一个测试字符串),但匹配项的长度是非从第一个到最后一个递减。因此,使用 re.search
获得的第一个匹配是最长的匹配。
任务是找到一组最长的序列
例如,给定 DNA 序列:"AGATCAGATCTTTTTTCTAATGTCTAGGATATATCAGATCAGATCAGATCAGATCAGATC"
它出现了 7 次 AGATC。 (AGATC)
匹配所有匹配项。
是否可以编写一个只捕获最长序列的正则表达式,即给定文本中的 AGATCAGATCAGATCAGATCAGATC
?
如果仅使用正则表达式这是不可能的,我如何遍历 python 中的每个序列(即第一个序列是 AGATCAGATC
、第二个 - AGATCAGATCAGATCAGATCAGATC
等等)?
使用:
import re
sequence = "AGATCAGATCTTTTTTCTAATGTCTAGGATATATCAGATCAGATCAGATCAGATCAGATC"
matches = re.findall(r'(?:AGATC)+', sequence)
# To find the longest subsequence
longest = max(matches, key=len)
解释:
非捕获组(?:AGATC)+
+
量词——匹配一次到无限次,尽可能多。AGATC
按字面匹配字符 AGATC(区分大小写)
结果:
# print(matches)
['AGATCAGATC', 'AGATCAGATCAGATCAGATCAGATC']
# print(longest)
'AGATCAGATCAGATCAGATCAGATC'
您可以测试正则表达式 here
。
使用re.finditer()
遍历所有匹配项。然后使用 max()
和一个键函数来找到最长的。让它成为一个函数,这样你就可以使用不同的组。
import re
def find_longest(sequence, group):
# build pattern
pattern = fr"(?:{group})+"
# iterate over all matches
matches = (match[0] for match in re.finditer(pattern, sequence))
# find the longest
return max(matches, key=len)
seq = "AGATCAGATCTTTTTTCTAATGTCTAGGATATATCAGATCAGATCAGATCAGATCAGATC"
find_longest(seq, "AGATC")
中心问题是,“是否可以编写一个只捕获最长序列的正则表达式?”答案是肯定的:
import re
s = 'AGATC_AGATCAGATC_AGATCAGATCAGATC_AGATC_AGATCAGATC'
m = re.search(r'((?:AGATC)+)(?!.*)', s)
print m.group() if m else ''
#=> "AGATCAGATCAGATC"
Regex demo<¯\(ツ)/¯>Python demo
Python 的正则表达式引擎执行以下操作。
( begin capture group 1
(?:AGATC) match 'AGATC' in a non-capture group
+ execute the non-capture group 1+ times
) end capture group 1
(?! begin a negative lookahead
.* match 0+ characters
match the content of capture group 1
) end the negative lookahead
对于上面的字符串 s
,AGATC
将首先被匹配,但否定前瞻会发现 AGATC
作为 AGATCAGATC
的第一部分,因此暂定匹配会被拒绝。然后 AGATCAGATC
将被匹配,但否定前瞻会发现 AGATCAGATC
作为 AGATCAGATCAGATC
的第一部分,因此临时匹配也将被拒绝。接下来,AGATCAGATCAGATC
将被匹配并接受,因为否定先行不会在字符串后面找到该匹配项。 (re.findall
与 re.search
不同,它还会匹配字符串末尾的 AGATCAGATC
。)
如果使用了 re.findall
,最长的匹配项之后可能会有多个匹配项(请参阅正则表达式演示 link 处的最后一个测试字符串),但匹配项的长度是非从第一个到最后一个递减。因此,使用 re.search
获得的第一个匹配是最长的匹配。