Python для извлечения данных из файла - PullRequest
1 голос
/ 19 марта 2010

Я пытаюсь извлечь текст, который имеет определенный текстовый файл:

----
data1
data1
data1
extractme
----
data2
data2
data2
----
data3
data3
extractme
----

и затем сбросьте его в текстовый файл, чтобы

----
data1
data1
data1
extractme
---
data3
data3
extractme
---

Спасибо за помощь.

Ответы [ 4 ]

5 голосов
/ 19 марта 2010

Это работает достаточно хорошо для меня. Ваш пример данных находится в файле с именем «data.txt», а вывод идет в «result.txt»

inFile = open("data.txt")
outFile = open("result.txt", "w")
buffer = []
keepCurrentSet = True
for line in inFile:
    buffer.append(line)
    if line.startswith("----"):
        #---- starts a new data set
        if keepCurrentSet:
            outFile.write("".join(buffer))
        #now reset our state
        keepCurrentSet = False
        buffer = []
    elif line.startswith("extractme"):
        keepCurrentSet = True
inFile.close()
outFile.close()
5 голосов
/ 19 марта 2010

Я предполагаю, что изменение количества тире (4 на входе, иногда 4, а иногда 3 на выходе) является ошибкой и фактически нежелательно (поскольку на алгоритм не даже намекают, чтобы объяснить, сколько тире вывод на разные случаи).

Я бы структурировал задачу по чтению и получению одного блока строк за раз:

def readbyblock(f):
  while True:
      block = []
      for line in f:
          if line = '----\n': break
          block.append(line)
      if not block: break
      yield block

, чтобы (выборочный) выход можно было аккуратно отделить от входа:

with open('infile.txt') as fin:
    with open('oufile.txt', 'w') as fou:
        for block in readbyblock(fin):
            if 'extractme\n' in block:
                fou.writelines(block)
                fou.write('----\n')

Это не является оптимальным с точки зрения производительности, если блоки большие, поскольку он имеет отдельный цикл для всех строк в блоке, подразумеваемых в предложении if. Итак, хороший рефакторинг может быть:

def selectivereadbyblock(f, marker='extractme\n'):
  while True:
      block = []
      extract = False
      for line in f:
          if line = '----\n': break
          block.append(line)
          if line==marker: extract = True
      if not block: break
      if extract: yield block

with open('infile.txt') as fin:
    with open('oufile.txt', 'w') as fou:
        for block in selectivereadbyblock(fin):
            fou.writelines(block)
            fou.write('----\n')

Параметризация разделителей (теперь жестко закодированных как «---- \ n» как для входа, так и для вывода) - еще один разумный твик кодирования.

2 голосов
/ 19 марта 2010

Для Python2

#!/usr/bin/env python

with open("infile.txt") as infile:
    with open("outfile.txt","w") as outfile:
        collector = []
        for line in infile:
            if line.startswith("----"):
                collector = []
            collector.append(line)
            if line.startswith("extractme"):
                for outline in collector:
                    outfile.write(outline)

Для Python3

#!/usr/bin/env python3

with open("infile.txt") as infile, open("outfile.txt","w") as outfile:
    collector = []
    for line in infile:
        if line.startswith("----"):
            collector = []
        collector.append(line)
        if line.startswith("extractme"):
            for outline in collector:
                outfile.write(outline)
1 голос
/ 19 марта 2010
data=open("file").read().split("----")
print '----'.join([ i for i in data if "extractme" in i ])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...