Возьмите ключевое слово и текст между ключевыми словами в Python

Во-первых, я хотел бы сказать, что это место помогло мне больше, чем я когда-либо мог отплатить. Я хотел бы сказать спасибо всем, кто помог мне в прошлом :).

Я пытаюсь разделить некоторый текст из сообщения определенного стиля. Он оформляется так:

DATA|1|TEXT1|STUFF: some random text|||||
DATA|2|TEXT1|THINGS: some random text and|||||
DATA|3|TEXT1|some more random text and stuff|||||
DATA|4|TEXT1|JUNK: crazy randomness|||||
DATA|5|TEXT1|CRAP: such random stuff I cant believe how random|||||

У меня есть код, показанный ниже, который объединяет текст, добавляя пробел между словами, и добавляет его в строку с именем «ТЕКСТ», поэтому он выглядит так:

STUFF: some random text THINGS: some random text and some more random text and stuff JUNK: crazy randomness CRAP: such random stuff I cant believe how random

Мне нужно, чтобы он был отформатирован следующим образом:

DATA|1|TEXT1|STUFF: |||||
DATA|2|TEXT1|some random text|||||
DATA|3|TEXT1|THINGS: |||||
DATA|4|TEXT1|some random text and|||||
DATA|5|TEXT1|some more random text and stuff|||||
DATA|6|TEXT1|JUNK: |||||
DATA|7|TEXT1|crazy randomness|||||
DATA|8|NEWTEXT|CRAP: |||||
DATA|9|NEWTEXT|such random stuff I cant believe how random|||||

Номера строк просты, я сделал это, а также возврат каретки. Что мне нужно, так это взять «дерьмо» и изменить часть, которая говорит «TEXT1», на «NEWTEXT».

Мой код сканирует строку в поисках ключевых слов, затем добавляет их в свою собственную строку, затем добавляет текст под ними, за которым следует следующее ключевое слово в отдельной строке и т. д. Вот мой код, который у меня есть до сих пор:

#this combines all text to one line and adds to a string
while current_segment.move_next('DATA')
    TEXT = TEXT + " " + current_segment.field(4).value

KEYWORD_LIST  = [STUFF:', THINGS:', JUNK:']
KEYWORD_LIST1 = [CRAP:']

#this splits the words up to search through
TEXT_list = TEXT.split(' ')

#this searches for the first few keywords then stops at the unwanted one
for word in TEXT_list:
    if word in KEYWORD_LIST:
        my_output = my_output + word
    elif word in KEYWORD_LIST1:
        break
    else:
        my_output = my_output + ' ' + word

#this searches for the unwanted keywords leaving the output blank until it reaches the wanted keyword
for word1 in TEXT_list:
    if word1 in KEYWORD_LIST:
        my_output1 = ''
    elif word1 in KEYWORD_LIST1:
        my_output1 = my_output1 + word1 + '\n'
    else:
        my_output1 = my_output1 + ' ' + word1

#my_output is formatted back the way I want deviding up the text into 65 or less character lines

MAX_LENGTH = 65
my_wrapped_output  = wrap(my_output,MAX_LENGTH)
my_wrapped_output1 = wrap(my_output1,MAX_LENGTH)
my_output_list     = my_wrapped_output.split('\n')
my_output_list1    = my_wrapped_output1.split('\n')

for phrase in my_output_list:
     if phrase == "":
          SetID +=1
          output = output + "DATA|" + str(SetID) + "|TEXT| |||||"
     else:
          SetID +=1
          output = output + "DATA|" + str(SetID) + "|TEXT|" + phrase + "|||||"

for phrase2 in my_output_list1:
     if phrase2 == "":
          SetID +=1
          output = output + "DATA|" + str(SetID) + "|NEWTEXT| |||||"
     else:
          SetID +=1
          output = output + "DATA|" + str(SetID) + "|NEWTEXT|" + phrase + "|||||"

#this populates the fields I need
value = output

Затем я форматирую «my_output» и «my_output1», добавляя слово «NEWTEXT» туда, куда оно идет. Этот код проходит через каждую строку в поисках ключевого слова, затем вставляет это ключевое слово и возвращает каретку. Как только он получает другой «KEYWORD_LIST1», он останавливается и удаляет остальную часть текста, а затем запускает следующий цикл. Моя проблема в том, что приведенный выше код дает мне это:

DATA|1|TEXT1|STUFF: |||||
DATA|2|TEXT1|some random text|||||
DATA|3|TEXT1|THINGS: |||||
DATA|4|TEXT1|some random text and|||||
DATA|5|TEXT1|some more random text and stuff|||||
DATA|6|TEXT1|JUNK: |||||
DATA|7|TEXT1|crazy randomness|||||
DATA|8|NEWTEXT|crazy randomness|||||
DATA|9|NEWTEXT|CRAP: |||||
DATA|10|NEWTEXT|such random stuff I cant believe how random|||||

Он берет текст перед «KEYWORD_LIST1» и добавляет его в раздел NEWTEXT. Я знаю, что есть способ сделать группы из ключевого слова и текста после него, но я не понимаю, как это реализовать. Любая помощь приветствуется.

Спасибо.

Вот что мне пришлось сделать, чтобы заставить его работать на меня:

KEYWORD_LIST  = ['STUFF:', 'THINGS:', 'JUNK:']
KEYWORD_LIST1 = ['CRAP:']

def text_to_message(text):
    result=[]
    for word in text.split():
        if word in KEYWORD_LIST or word in KEYWORD_LIST1:
            if result:
            yield ' '.join(result)
            result=[]
            yield word
        else:
            result.append(word)
    if result:
        yield ' '.join(result)

def format_messages(messages):
    title='TEXT1'
    for message in messages:
        if message in KEYWORD_LIST:
            title='TEXT1'
        elif message in KEYWORD_LIST1:
            title='NEWTEXT'
    my_wrapped_output  = wrap(message,MAX_LENGTH)
    my_output_list     = my_wrapped_output.split('\n')
    for line in my_output_list:
        if line = '':
            yield title + '|'
        else:
            yield title + '|' + line

for line in format_messages(text_to_message(TEXT)):
    if line = '':
        SetID +=1
        output = "DATA|" + str(SetID) + "|"
    else:
        SetID +=1
        output = "DATA|" + str(SetID) + "|" + line

#this is needed instead of print(line)
value = output 

person Opy    schedule 19.09.2011    source источник
comment
По соглашению, ALL_CAPS и обычный регистр не смешиваются в именах переменных. Ваш TEXT_list мог бы быть более точно назван text_list. Просто небольшое замечание.   -  person brc    schedule 20.09.2011
comment
Я мог бы попробовать модуль csv, а не делать это самостоятельно.   -  person Dave    schedule 20.09.2011
comment
brc, это, должно быть, пролилось из моего java-кодирования, лол. Я обновил выше, чтобы дать более подробную информацию.   -  person Opy    schedule 20.09.2011
comment
@Opy: Пожалуйста, покажите ввод (TEXT?) и желаемый вывод.   -  person unutbu    schedule 20.09.2011
comment
Извините, ТЕКСТ — это длинная строка данных после объединения всех строк. TEXT_list создается в разделенной части кода. Я вставил остальную часть своего кода, чтобы вы могли видеть, как он отформатирован так, как я хочу. Я должен был добавить это с самого начала, но я решил, что простое исправление моего оператора if/else исправит это. Похоже, мне придется пойти с регулярным выражением.   -  person Opy    schedule 20.09.2011


Ответы (1)


  1. Общий совет: не пытайтесь наращивать строки следующим образом:

    my_output = my_output + ' ' + word
    

    вместо этого создайте my_output список, добавьте word к списку, а затем, в самом конце, выполните одно соединение: my_output = ' '.join(my_output). (См. пример кода text_to_message ниже.) Использование соединения правильный способ построения строк. Задержка создания строки полезна, потому что обработка списков подстрок более приятна, чем разбиение и неразбиение строк, и необходимость добавлять пробелы и возвраты каретки тут и там.

  2. Изучите генераторы. Их легко понять, и они могут очень помочь вам при обработке такого текста.


import textwrap

KEYWORD_LIST  = ['STUFF:', 'THINGS:', 'JUNK:']
KEYWORD_LIST1 = ['CRAP:']

def text_to_message(text):
    result=[]
    for word in text.split():
        if word in KEYWORD_LIST or word in KEYWORD_LIST1:
            if result:
                yield ' '.join(result)
                result=[]
            yield word
        else:
            result.append(word)
    if result:
        yield ' '.join(result)

def format_messages(messages):
    title='TEXT1'
    num=1
    for message in messages:
        if message in KEYWORD_LIST:
            title='TEXT1'
        elif message in KEYWORD_LIST1:
            title='NEWTEXT'
        for line in textwrap.wrap(message,width=65):
            yield 'DATA|{n}|{t}|{l}'.format(n=num,t=title,l=line)
            num+=1

TEXT='''STUFF: some random text THINGS: some random text and some more random text and stuff JUNK: crazy randomness CRAP: such random stuff I cant believe how random'''

for line in format_messages(text_to_message(TEXT)):
    print(line)
person unutbu    schedule 19.09.2011
comment
Я надеялся, что не упустил слишком много деталей, но, кажется, упустил. Перед кодом, который я перечислил выше, он берет все слова и объединяет их вместе, добавляя пробел между каждым словом, поэтому на самом деле он ищет ключевые слова, затем добавляет ключевое слово в свою собственную строку, а затем текст ниже, который ищет следующее ключевое слово. Как только он проходит через приведенный выше код, он делит его на строки длиной не более 65 символов, используя какой-либо другой код. Таким образом, TEXT_list выше — это одна строка, в которой весь текст за исключением DATA|1|TEXT1| и конечный |||||. Также ключевые слова могут отличаться друг от друга. - person Opy; 20.09.2011
comment
Я отредактировал свой пост выше, чтобы быть более понятным. Я проверю то, что вы написали, потому что похоже, что это может помочь :) - person Opy; 20.09.2011
comment
Я отредактировал вопрос, чтобы сделать его более точным. Пока спасибо за помощь :) - person Opy; 20.09.2011
comment
Гораздо лучше, но ему не нравится слово «урожайность». Я получаю синтаксическую ошибку во всех строках с доходностью. - person Opy; 20.09.2011
comment
Вы смешиваете return и yield в одной и той же функции? Это нет-нет. Если нет, вы должны опубликовать свой код. - person unutbu; 20.09.2011
comment
Мой код точно такой же, как вы написали выше. Я могу поставить # перед строкой с yield, и синтаксическая ошибка покажет следующую строку с yield. Он продолжает делать это для каждой строки, в которой есть доходность. Есть ли другой способ получить данные, кроме выхода? - person Opy; 20.09.2011
comment
хорошо, мне пришлось добавить генераторы импорта из будущего, чтобы включить его в этом программном обеспечении. Я думаю, это только с использованием python 2.2. Моя следующая проблема заключается в том, что я не думаю, что это программное обеспечение имеет модуль textwrap для импорта. И здесь я думал, что это будет простой проект, лол. - person Opy; 20.09.2011
comment
@Opy: Хм, ну, в вашем собственном коде использовалась какая-то функция с именем wrap. Возможно, замените его на textwrap.wrap. - person unutbu; 21.09.2011
comment
Функция переноса была в другом скрипте в этой программе (есть около 20 мест для разных скриптов Python, лол). Вероятно, они написали этот сценарий, потому что не было обтекания текстом. Я также иду за чужими сценариями и пытаюсь работать с тем, что у них есть. Вот почему весь вывод = вывод + слово и другие прикольные вещи, лол. Эта программа имеет ограниченное количество Python, а не весь язык. - person Opy; 21.09.2011
comment
Это все еще требует некоторой настройки, но это работает! Он ставит одну букву в строку, поэтому мне просто нужно исправить то, что я там напортачил, лол. Бесконечно благодарен! - person Opy; 21.09.2011
comment
Хорошо, я заработал на 100%, я разместил свой рабочий код выше. Спасибо еще раз за помощь! :) - person Opy; 21.09.2011