#python #regex #string #file #extract
#python #регулярное выражение #строка #файл #извлечение
Вопрос:
Доброе раннее утро,
У меня есть следующий файл регулярных выражений python, который мы создали в предыдущем сообщении. Это предназначено для извлечения любой информации, которая выглядит как ‘chr’ number ‘:’ bignumber «..» bignumber (так что это выглядит как chr1: 100000 ..120000) если chr1 переключен на chrX, скрипт регулярных выражений больше не работает…
Вот оригинальный сценарий :
# Opens each file to read/modify
infile='myfile.txt'
outfile='outfile.txt'
#import Regex
import re
with open (infile, mode='r', buffering=-1) as in_f, open (outfile, mode='w', buffering=-1) as out_f:
f = (i for i in in_f if 't' in i.rstrip())
for line in f:
_, k = line.split('t',1)
x = re.findall(r'^1..100t([ -])chr(d ):(d )..(d ). $',k)
if not x:
continue
out_f.write(' '.join(x[0]) 'n')
Если я изменил эту строку :
x = re.findall(r'^1..100t([ -])chrX(d ):(d )..(d ). $',k)
Я не могу извлечь конкретно то, что выглядит как chrX и т. Д…
Также вы должны знать, что некоторые строки могут быть пустыми!
Помогите, пожалуйста Спасибо
Комментарии:
1. строка, которая, по вашим словам, изменена, полностью совпадает
2. Вы ничего не говорите о
123100␉
префиксе. Может ли это быть проблемой? Пожалуйста, покажите содержимое k (useprint repr(k)
), которое соответствует и которое не соответствует.
Ответ №1:
Я не совсем понимаю ваш вопрос, но я попытаюсь дать несколько советов, основанных на вашем коде.
Вот самая важная строка:
x = re.findall(r'^1..100t([ -])chr(d ):(d )..(d ). $',k)
Наблюдения:
0) Я даже не знаю, что buffering=-1
будет делать при вызове open()
. Я рекомендую вам избавиться от этого и разрешить стандартное поведение, которое является буферизацией строк. Это то, что вам нужно для этого случая, когда вы хотите обрабатывать файл по одной строке за раз. (Значение по умолчанию такое же, как указано buffering=1
.)
1) re.findall()
возвращает список совпадений. Однако, используя $
в своем шаблоне, вы гарантируете, что получите не более одного совпадения, потому что каждая строка может иметь только один конец строки. Поэтому вам, вероятно, следует использовать re.search()
. Вы могли бы даже использовать re.match()
, поскольку у вас есть ^
привязка к началу строки.
2) Я не рекомендую вам использовать .split()
метод function, чтобы избавиться от ведущей вкладки. Просто добавьте табуляцию в ваше регулярное выражение. Это проще и быстрее.
3) Ваш шаблон требует, чтобы каждая строка начиналась со строки, подобной этой:
1aa100
100100
1xx100
1xy100
Это то, что вы хотели? Начинается ли каждая строка с числа, которое всегда заканчивается на «100»? Если это всегда число, которое вы можете использовать d
вместо .
шаблона.
4) Вам требуется табуляция после числа, подобного приведенному выше. Тогда у вас есть группа совпадений, которая соответствует либо ‘ ‘, либо ‘-‘ и позволяет собирать совпадающее значение. Мне любопытно, что вы будете с этим делать.
5) Шаблон chrd
будет соответствовать chr0
, chr1
, chr11
, chr111
, и т.д. Любая комбинация цифр с минимальной длиной в 1 цифру. Я не уверен, ожидаете ли вы, что она действительно будет соответствовать заглавной букве «X» (вы говорили о сопоставлении chrX
), но это определенно не так.
6) Вы сопоставляете число, два фактических периода и другое число. Для меня это выглядит совершенно правильно и хорошо. Затем, после второго числа, вы используете a .
и a
вместе. Для этого требуется один или несколько дополнительных символов до конца строки. Мне интересно, является ли это причиной вашей проблемы. Возможно, вам следует использовать .*
which соответствует нулю или более дополнительных символов?
7) Если вы используете re.match()
вместо re.findall()
, вам не нужно будет использовать x[0]
, чтобы попасть в группу совпадений.
8) Если у вас есть группа совпадений m
, ' '.join(m)
не работает. Вы получаете ошибку типа. Вместо этого вам нужно использовать ' '.join(m.groups())
.
9) Я думаю, что шаблон с chr
и двумя числами, разделенными ..
, сам по себе довольно хорош, поэтому, возможно, вы можете ослабить остальную часть шаблона и просто сопоставить их.
10) Мне всегда нравится предварительно компилировать свои шаблоны регулярных выражений. Это быстрее, и тогда вы можете использовать функции метода для скомпилированного шаблона. Например, if pat
является предварительно скомпилированным регулярным выражением, которое можно использовать pat.search(line)
для поиска строки текста.
Соберите мои предложения, и вот некоторый код Python, который вы можете попробовать:
import re
infile='myfile.txt'
outfile='outfile.txt'
pat = re.compile(r'([ -])chr([^:] ):(d )..(d )')
with open(infile, mode='r') as in_f, open(outfile, mode='w') as out_f:
for line in in_f:
if 't' not in line.rstrip():
continue
m = pat.search(line)
if not m:
continue
out_f.write(' '.join(m.groups()) 'n')
РЕДАКТИРОВАТЬ: поскольку вы, похоже, хотите распознать строку chrX
как действительную, я изменил приведенный выше пример кода. Вместо d
сопоставления с цифрой теперь используется [^:]
для сопоставления с чем угодно, кроме двоеточия. Приведенный выше код должен соответствовать chr1:
, chrX:
, или почти всему остальному сейчас.
Комментарии:
1. ВАУ, большое спасибо. Прямо сейчас я вижу, что в моем исходном сообщении была вставлена опечатка. Если у меня есть chr[number]:[int}] .. [int] это работает, но затем, когда мне нужно извлечь chr [букву]: [int].. [int] это вообще не сработало. Кажется, что он не распознает буквы, а только цифры. Это была моя точка зрения. Большое спасибо, я попробую ваши предложения завтра и обновлю этот пост. Спасибо!
2. Эй, мне нужно немного адаптировать этот код к нашим данным. Я снова сталкиваюсь с проблемами.. Должен ли я опубликовать новый вопрос или вы можете проверить его здесь?
3. @madkitty, ты мог бы сделать это в любом случае. Если вы опубликуете вопрос, кто-то, кроме меня, может ответить на него за вас, и вы можете получить ответ быстрее. Если вы публикуете вопрос, вы должны включить обратную ссылку на этот вопрос.