Вставить новую строку после шаблона с индексом строки и записать в новый файл - PullRequest
0 голосов
/ 02 мая 2019

Я новичок в Python, и я прошел через несколько публикаций на Python, учебные сайты и исходные документы, чтобы решить мою проблему, однако я еще не совсем там!

Что я пытаюсь сделать: у меня есть текстовый файл с несколькими строками, где я сначала ищу блоки текстов, помеченных от одного вхождения «MARKERSTRING» к другому. «MARKERSTRING» встречается несколько раз по всему тексту, но только некоторые из них имеют «TAILSTRING» внутри блока. Если найдено, то я хочу добавить новую строку ("newstring") прямо под последним вхождением строки "BODY" в том же блоке.

Я хочу сохранить все строки в новом файле и вставить новую строку с указанным индексом «BODY» (последнее вхождение в блоке)

Содержимое моего текстового файла выглядит так:

Multiple lines with some other text

MARKERSTRING SOMESTRING SOME OTHER STRING #

BODY A B C
BODY V G H
BODY Y U I

TAILSTRING X1 Y
TAILSTRING X2 Y


MARKERSTRING SOMESTRING SOME OTHER STRING # 

### #Although I want to append this to my file I dont want to process my #function through this as it does not have "TAILSTRING"

BODY B C
BODY V G H J
BODY Y U I

### #But want this block:

MARKERSTRING SOMESTRING SOME OTHER STRING #

BODY B C
BODY V G H J


TAILSTRING X1 Y
TAILSTRING X2 Y


Multiple lines with some other text

END

Мои проблемы заключаются в следующем:

  1. Моя функция, которая получает индекс и вставляет новую строку, возвращает только первое вхождение. Это может быть проблемой с позиционированием оператора return, но если сделать отступ больше, он пожалуется на «UnboundLocalError». Если я использую функцию yield, то она возвращает объект. Я хочу написать новую строку в этой функции

  2. Вторая часть, которая ищет «MARKERSTRING», добавляет все строки в буфер, а затем вызывает мою функцию, продолжает добавлять строки несколько раз, не вставляя новую строку. Это, вероятно, происходит потому, что я начинаю искать необходимые шаблоны внутри цикла for, который выбирает каждую строку в файле.

Есть ли лучший способ сделать это без добавления каждой строки внутри цикла for?

Примерно так:

import re
from operator import itemgetter
import itertools


### The Function #########
def myfunc(filename):
    highest = None
    for cnt, line in enumerate(filename):

        if line.startswith("BODY "):
            bline = line.split()

            highest = cnt

        if line.startswith("TAIL"):
            lpline = line.split()
            print(lpline)
            newline = "BOND", lpline[2], lpline[4]

            newstring = ' '.join((str(x)) for x in newline)

            bline.insert(highest + 1, newstring) ##This doesnt insert
            return bline

### The "Markerstring" finder snippet: Keeps iterating over all lines #####

filename = open("input.txt").readlines()
outfilename = open("result.txt", 'w+')
buffer = []
keepCurrentSet = True
for line in filename:
    buffer.append(line)
    if (line.startswith('MARKERSTRING '):
        if keepCurrentSet:
            outfilename.write("".join(buffer))

            myfunc(filename)

Ожидаемый результат:

Multiple lines with some other text


MARKERSTRING SOMESTRING SOME OTHER STRING #

BODY A B C
BODY V G H
BODY Y U I
BODY X1 Y     #Inserted line = newstring
BODY X2 Y     #Inserted line = newstring


TAILSTRING X1 Y
TAILSTRING X2 Y


MARKERSTRING SOMESTRING SOME OTHER STRING # 

### #Although I want to append this to my file I dont want to process my #function through this as it does not have "TAILSTRING"

BODY B C
BODY V G H J
BODY Y U I


### #But want this block:

MARKERSTRING SOMESTRING SOME OTHER STRING #


BODY B C
BODY V G H J
BODY X1 Y        #Inserted line = newstring
BODY X2 Y        #Inserted line = newstring

TAILSTRING X1 Y
TAILSTRING X2 Y

Multiple lines with some other text

END

1 Ответ

0 голосов
/ 02 мая 2019

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

Однако я нашел решение, которое, я думаю, работает.

РЕДАКТИРОВАТЬ: Чтобы ответить на ваши вопросы в разделе комментариев (ниже),

_, params = line.split(maxsplit = 1)

Это делится на 2 элемента для значения maxsplit 1. '_' - это заполнитель для получения (и игнорирования) первого элемента разделения, TAILSTRING,Второй элемент из разделения (X1 Y или X2 Y) назначен на params.

Позже я также хочу убедиться, что BODY X1 Y1 еще не присутствует втот же самый блок MARKERSTRING, на который я смотрю

Для этого необходимо изменить код.

fin = open('f01.txt', 'r')
fout = open('temp.txt', 'w')

buffer = []
idx = 0

for line in fin:
    line = line.rstrip()
    buffer.append(line)
    if line.startswith('MARKERSTRING'):
        for item in buffer:
            fout.write(item + "\n")
        buffer = []
        idx = 0
        # continue because don't want to increment idx at bottom of loop
        # idx should be 0 for this iteration
        continue
    elif line.startswith('BODY'):
        max_body_idx = idx
    elif line.startswith('TAILSTRING'):
        _, params = line.split(maxsplit = 1)
        buffer.insert(max_body_idx+1, 'BODY ' + params)
        max_body_idx += 1
    idx += 1

fin.close()

# print out last record
for item in buffer:
    fout.write(item + "\n")

fout.close()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...