#python #regex #string #dictionary #substring
#python #регулярное выражение #строка #словарь #подстрока
Вопрос:
Я надеюсь, что вы сможете указать мне правильное направление, поскольку я новичок в программировании и Python в частности. Я пытаюсь найти максимальное количество повторений определенных подстрок в строке большего размера. Например, сколько раз 'AGATC'
повторяется в гораздо более длинной строке (она может появляться только в одном месте, но четыре раза подряд в другом месте).
Я читал о регулярных выражениях для этого и написал приведенный ниже код. Она успешно распечатает повторения для каждого шаблона отдельно, однако мне нужно знать количество повторений, когда оно появится. Пример вывода моего кода выглядит следующим образом:
['AGATCAGATCAGATCAGATC', 'TATCTATCTATCTATCTATC', 'GAAA', 'GATA', 'AATG', 'GAAA', 'GAAA', 'GATA']
В этом случае 'AGATC'
появляется четыре раза, но 'TATC'
повторяется пять раз, поэтому мне нужно это как целое число. Если у кого-нибудь, пожалуйста, есть какие-либо идеи, чтобы продвинуть меня вперед, я был бы глубоко признателен.
Вот мой полный код:
import re
# Opens the textfile and stores it as a string
with open('STR.txt') as strfile:
for row in strfile:
STRs = row
# Defines patterns we are searching for in STR
pattern1 = (r'(?:AGATC) ')
pattern2 = (r'(?:TTTTTTCT) ')
pattern3 = (r'(?:AATG) ')
pattern4 = (r'(?:TCTAG) ')
pattern5 = (r'(?:GATA) ')
pattern6 = (r'(?:TATC) ')
pattern7 = (r'(?:GAAA) ')
pattern8 = (r'(?:TCTG) ')
# Recompiles all patterns into one single pattern
mainpattern = re.compile("(%s|%s|%s|%s|%s|%s|%s|%s)" % (pattern1, pattern2, pattern3, pattern4, pattern5, pattern6, pattern7, pattern8))
# Finds the pattern matches in STR
STR_match = re.findall(mainpattern, STRs)
print(STR_match)
Комментарии:
1. Если я вас правильно понимаю, вам не нужны повторяющиеся строки (например, ‘AGATCAGATCAGATCAGATCAGATC’, а вместо этого 4 одиночных совпадения), которые вы можете затем посчитать. Если это верно, вам просто нужно удалить » » из вашего шаблона поиска и проверить длину списка результатов.
2. Что-то вроде того, что мне нужно, это подсчитать количество повторений в случае ‘AGATCAGATCAGATCAGATC’, которое соответствовало бы 4, но если AGATC появится в другом месте строки, я получу 5, и это было бы неверно, поскольку мне нужно подсчитать максимальное количество повторений в любой позиции строки. К сожалению, я думаю, что удаление then может привести к неправильным результатам?
3. Ах, так вы хотите максимальное количество последовательных повторений любого из шаблонов? Например, в вашем примере 5 для
TATC...
части?4. Именно это я и пытаюсь выяснить.
Ответ №1:
Если я правильно понимаю вашу проблему, вы могли бы сделать это отдельно для каждого шаблона, например, что-то вроде:
patterns = ('AGATC', 'TTTTTTCT', 'AATG', 'TCTAG', ...)
max_len = 0
max_pattern = None
for pattern in patterns:
match = re.findall(f'(?:{pattern}) ', STRs)
if match:
longest = sorted(match)[-1] # last is the longest match
l = len(longest)/len(pattern)
if l > max_len:
max_len = l
max_pattern = pattern
print(f"{max_len} x {max_pattern}")
Это сопоставление вернет список всех последовательных совпадающих строк, и если вы отсортируете их в алфавитном порядке, самая длинная строка всегда будет последней, поскольку они повторяют шаблон. Затем вы можете вычислить количество повторений шаблона в этой строке.
Если вам просто нужно самое длинное повторение, вы можете вычислить максимальное из этих чисел, как показано.
Комментарии:
1. Спасибо, кажется, это возвращает правильное число (и я думаю, что я понимаю логику, стоящую за этим). Сейчас я пытаюсь изменить код, чтобы напечатать, какой шаблон был обнаружен так много раз, например, ‘AGATC’ был обнаружен 4 раза.
2. Я адаптировал код. Если вам нужны все шаблоны с максимальной длиной, вам придется немного изменить ее, но с этим вы, вероятно, сможете разобраться сами.
3. Большое вам спасибо! Я разобрался с этой версией (я изменил имя некоторых переменных): STR_name = longest[:int(len(longest)/STR_max)] Вы действительно сделали мой день, помогая мне, я действительно ценю это.