2013-04-06 1 views
1

Я пытаюсь использовать регулярные выражения в Python для синтаксического анализа большого текстового файла с разделителями табуляции по строке и печатать строки, в которых строка содержит 5 или более экземпляров 0/1 или 1/1.Как напечатать только строки с пятью или более совпадениями регулярного выражения?

Мой сценарий почти есть, но я борюсь с 5 или более экземплярами.

Это напечатает строки одним совпадением.

import re 
f = open ("infile.txt", "r") 
out = open("outfile.txt", "w") 

for line in f: 
    if re.match(r"(.*)(0|1)/(1)(.*)", line): 
     print >> out, line, 

Чтобы напечатать только те строки, которые имеют 5 или больше матчей я пытался findall и finditer следующим образом, но они не работали:

for line in f: 
    x = len(re.findall(r"(.*)(0|1)/(1)(.*)", line)): 
    if x > 5: 
     print >> out, line, 

Может кто-нибудь помочь мне с этим?

Вот пример одной строки из текстового файла (все пространства вкладки в файле):

X 6529 . C A,G PASS AC=4,2;AF=0.6777 1/1:0,20 0/1:0,16 0/1:0,16 0/0:4,16 0/0:3,1 
+1

Как это не работает? Можете ли вы исправить ваш отступ? – tacaswell

ответ

1

Вы можете использовать {5}, чтобы соответствовать шаблону 5 или более раз

import re 
f = open ("data.txt", "r") 
out = open("dataout.txt", "w") 

for line in f: 
    if re.match(r"(.*([01]/1.*){5,}", line): 
     print >> out, line, 
0

Я думаю, что есть два решения, которые могут работать. Первая палочка с вашей текущей идеей делать findall с рисунком, который соответствует одному событию 0/1 или 1/1. Во-вторых, сделать один шаблон, который будет соответствовать этому тексту пять раз подряд.

Для первого подхода, я думаю, все, что вам нужно сделать, это избавиться от битов .astericssymbol вашего текущего шаблона (я не совсем понимаю, почему это указано, а не .*, но это неправильно в любом случае). Вот код, который должен работать:

for line in f: 
    matches = re.findall(r'[01]/1', line) 
    if len(matches) >= 5: 
     print >> out, line, 

Я устранил захватив группы, которые не были необходимы, и могли бы сделать вещи немного медленнее.

Для второго подхода вы можете сделать только один звонок до re.search, который вернет значение не None, только если он найдет 5 соответствий соответствующего сортировки. В шаблоне используется синтаксис повторения {N}, чтобы найти точно N копии предыдущего шаблона. В этом случае нам нужно будет сопоставить дополнительные символы между значками 0/1 или 1/1, поэтому у шаблона есть .*. Поскольку мы хотим повторить все это, нам нужно обернуть его в группу, не связанную с захватом:

for line in f: 
    if re.search(r'(:?[01]/1.*){5}', line): 
     print >> out, line,