Как получить перекрывающиеся шаблоны с помощью Python finditer?

Я использую скрипт Python, который ищет шаблон в файле fasta. Он работает очень хорошо, но не возвращает перекрывающиеся строки. К сожалению, меня интересуют возможные перекрывающиеся строки. Поскольку я не программист (я просто пытаюсь изучить Python), мне было интересно, может ли кто-нибудь изменить скрипт, чтобы найти перекрывающиеся строки. Я думаю, что модуль регулярных выражений может это сделать, но я безуспешно пытался установить его на свой компьютер (Windows). Я получил это:

C:\Python33>regex-2014.02.19>python setup.py install
running install
running build
running build_py
runnning built_ext
building'_regex' extension
error:Unable to find vcvarsall.bat

Мне было бы проще работать с модифицированным скриптом. Итак, вот мой сценарий:

import re
import sys

psq_re_f= re.compile('G{3,}.{1,7}?G{3,}.{1,7}?G{3,}.{1,7}?G{3,}') #((?<=G)[^G]|(?<!G).)
psq_re_r= re.compile('C{3,}.{1,7}?C{3,}.{1,7}?C{3,}.{1,7}?C{3,}') #((?<=C)[^C]|(?<!C).)


filename = input('Enter the name of the input fasta file: ')
ref_seq_fh = open(filename)

outputfileg = open("strelkaindels_quadg.txt",'wt')
outputfilec = open("strelkaindels_quadc.txt",'wt')

outputfileg.write('#\tID\tEntry Length\tStart\tEnd\tLength\tStrand\tSequence\n')
outputfilec.write('#\tID\tEntry Length\tStart\tEnd\tLength\tStrand\tSequence\n')

count = 0
ref_seq = []
line = (ref_seq_fh.readline()).strip()
chr = re.sub('^>', '', line)
chr1 = chr.split (":")
#line = (ref_seq_fh.readline()).strip()
while True:
    while line.startswith('>') is False:
        ref_seq.append(line)
        line = (ref_seq_fh.readline()).strip()
        if line == '':
            break
    ref_seq = ''.join(ref_seq)
    for m in re.finditer(psq_re_f, ref_seq):
        count=count+1
        outputfileg.write('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s' %(count, chr1[0], len(ref_seq), m.start(), m.end(), len(m.group(0)), '+', m.group(0))+'\n')
    for m in re.finditer(psq_re_r, ref_seq):
        count=count+1
        outputfilec.write('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s' %(count, chr1[0], len(ref_seq), m.start(), m.end(), len(m.group(0)), '-', m.group(0))+'\n')
    chr = re.sub('^>', '', line)
    chr1 = chr.split (":")
    ref_seq = []
    line= (ref_seq_fh.readline()).strip()
    if line == '':
        break


outputfileg.close()
outputfilec.close()

Наконец, пример файла fasta (текстовый формат для представления нуклеотидных последовательностей), широко используемого в биологии:

>id_1
agatagatgatagatatagagagcgcgctagatcgatcgatcgagtcgatcgcgcggggggcccctctctctctatagggacatacga
>id_2
agacatcagatacagagatatttacataacaagagatacag
>id_3
cgctctagctcctcctctcgcgtagctagctctctctaacatgattagaattcagatcgatcgatcgatggttttttttctctct
and so on...

Например, представим следующую последовательность:

GGGTGGGTGGGCGGGAGGG

Скрипт вернет только эту строку:

GGGTGGGTGGGCGGG

Но я хотел бы также получить это:

GGGTGGGCGGGAGGG

person Frank_B    schedule 11.04.2014    source источник
comment
Я не думаю, что RegEx может поддерживать сопоставление перекрывающихся шаблонов.   -  person thefourtheye    schedule 11.04.2014
comment
Можете ли вы описать проблему, которую пытаетесь решить? Похоже, вы пытаетесь сопоставить каждую строку (последовательность) с последовательностью, которая имеет наибольшее перекрытие. Должны ли быть перекрытия на концах? Перекрывается ли gagttca с ccagttgg (потому что у них общий agtt) или это запрещено? На первый взгляд кажется, что у вас есть пример самой длинной общей подстроки, но если вы размещаете больше информации о своих целях, мы можем помочь вам легче.   -  person bgschiller    schedule 11.04.2014
comment
@bgschiller Я отредактировал свой вопрос (посмотрите в конце, я добавил пример). Надеюсь, теперь стало понятнее... Спасибо.   -  person Frank_B    schedule 11.04.2014


Ответы (1)


Вы можете попробовать использовать положительный прогноз:

(?=(G{3,}.{1,7}?G{3,}.{1,7}?G{3,}.{1,7}?G{3,}))

демонстрационная версия regex101

И в вашем коде вам придется изменить свои группы на .group(1), но m.end() будет таким же, как m.start(), поэтому вы можете немного обойти это, может быть, я использую len():

for m in re.finditer(psq_re_f, ref_seq):
    count=count+1
    outputfileg.write('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s' % (count,
                      chr1[0], len(ref_seq), m.start(),
                      m.start() + len(m.group(1)), len(m.group(1)),
                      '+',m.group(1))+'\n')
person Jerry    schedule 11.04.2014
comment
Я думаю, что изменения, которые вы предложили в отношении сопоставления шаблонов (и перекрытий), могут работать хорошо, но я не могу получить какие-либо отпечатки в своем выходном файле... Поскольку совпадений более 1, мне было интересно, может ли проблема возникнуть из строки метода записи. - person Frank_B; 11.04.2014
comment
@Frank_B Являются ли последовательности в ваших файлах строчными буквами? Если это так, вы можете сделать регулярное выражение нечувствительным к регистру: psq_re_f= re.compile(r'(?=(G{3,}.{1,7}?G{3,}.{1,7}?G{3,}.{1,7}?G{3,}))', re.IGNORECASE) - person Jerry; 11.04.2014
comment
@Frank_B Хм, я только что проверил последовательности от id_1 до id_3, и ни одна из них не соответствует шаблону, который вы ищете? Вы уверены, что они должны совпадать? - person Jerry; 12.04.2014
comment
Пример файла fasta (то есть идентификатор 1-3) был только примером файла fasta, чтобы помочь понять, что такое файл fasta для людей, не связанных с биологическими науками. Я просто набираю случайную последовательность, и в этом примере нет возможных совпадений... Единственный хороший пример для проверки шаблона: GGGTGGGTGGGCGGGAGGG. Извините за путаницу. - person Frank_B; 12.04.2014
comment
@Frank_B Хорошо, я только что запустил код, и у меня он работает нормально. С одной последовательностью файл strelkaindels_quadg.txt получает две строки. На всякий случай вот полный код: ссылка - person Jerry; 12.04.2014
comment
В приведенной выше демонстрационной ссылке regex101 вы добавляете модификатор g к шаблону. Я также добавил его в свой сценарий. Но если я этого не сделал, я получил 2 строки в файле strelkaindels.txt, и холостой ход вернул мне объект ‹_sre.SRE_Match по адресу 0x000000000337DB70› объект ‹_sre.SRE_Match по адресу 0x0000000003426E40›. Так что, похоже, теперь это работает. Как избавиться от тех строк, которые возвращаются бездействующими? - person Frank_B; 12.04.2014
comment
@Frank_B Нет, вы используете его так же, как в ссылке, которую я дал выше. Regex101 был в основном основан на регулярном выражении PCRE, но в python вы используете re.findall или re.finditer, как в вашем текущем коде. Кроме того, что вы подразумеваете под холостым ходом? Получение 'match object' означает, что вы не поставили .group(1) на совпадения. - person Jerry; 12.04.2014
comment
IDLE находится в меню «Пуск» (расшифровывается как «Интегрированная среда разработки»). Сюда я посылаю свои команды. Я получил две строки после запуска скрипта ‹_sre.SRE_Match object at 0x000000000320AEB8› ‹_sre.SRE_Match object at 0x000000000320AB70›. Но я также получил свои две строки в выходном файле. Так это работает! Я очень счастлив. Единственная проблема - это две строки, которые я получил в IDLE. Я впервые вижу этих персонажей. - person Frank_B; 12.04.2014
comment
@Frank_B Это то, что вы видите, когда печатаете объекты соответствия. Как таковые, они не очень полезны (AFAIK), но вы можете подключиться к ним, используя .group(), .start() и тому подобное. Документы о модуле re содержат более подробную информацию о том, что вы можете использовать с объектом. Не стесняйтесь пометить мой ответ как принятый :) - person Jerry; 12.04.2014