напечатать первый абзац в python

У меня есть книга в текстовом файле, и мне нужно распечатать первый абзац каждого раздела. Я думал, что если я найду текст между \n\n и \n, я смогу найти свой ответ. Вот мои коды, и это не сработало. Можете ли вы сказать мне, где я не прав?

lines = [line.rstrip('\n') for line in open('G:\\aa.txt')]

check = -1
first = 0
last = 0

for i in range(len(lines)):
    if lines[i] == "": 
            if lines[i+1]=="":
                check = 1
                first = i +2
    if i+2< len(lines):
        if lines[i+2] == "" and check == 1:
            last = i+2
while (first < last):
    print(lines[first])
    first = first + 1

Также я нашел код в stackoverflow, я тоже попробовал, но он просто напечатал пустой массив.

f = open("G:\\aa.txt").readlines()
flag=False
for line in f:
        if line.startswith('\n\n'):
            flag=False
        if flag:
            print(line)
        elif line.strip().endswith('\n'):
            flag=True

Я поделился образцом раздела этой книги ниже.

I

ОБЛАСТЬ ЗЕМЛИ

Перед нашими дверями лежит обширное поле захватывающих человеческих интересов, которое до сих пор мало исследовано. Это Поле Животного Интеллекта.

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

II

ТЕМПЕРАМЕНТ И ИНДИВИДУАЛЬНОСТЬ ДИКИХ ЖИВОТНЫХ

Что я пытаюсь сделать здесь, так это найти строки в верхнем регистре и поместить их все в массив. Затем, используя метод index, я найду первый и последний абзацы каждого раздела, сравнив индексы этих элементов этого созданного мной массива.

Вывод должен быть таким:

Перед нашими дверями лежит обширное поле захватывающих человеческих интересов, которое до сих пор мало исследовано. Это Поле Животного Интеллекта.

Что я пытаюсь сделать здесь, так это найти строки в верхнем регистре и поместить их все в массив. Затем, используя метод index, я найду первый и последний абзацы каждого раздела, сравнив индексы этих элементов этого созданного мной массива.


person Tuğcan Demir    schedule 02.01.2016    source источник
comment
можете ли вы добавить фактический ввод как есть и ожидаемый результат?   -  person Padraic Cunningham    schedule 03.01.2016


Ответы (5)


Если вы хотите сгруппировать разделы, вы можете использовать itertools.groupby, используя пустые строки в качестве разделителей:

from itertools import groupby
with open("in.txt") as f:
    for k, sec in groupby(f,key=lambda x: bool(x.strip())):
        if k:
            print(list(sec))

Еще с помощью itertools foo мы можем получить разделы, используя заголовок в верхнем регистре в качестве разделителя:

from itertools import groupby, takewhile

with open("in.txt") as f:
    grps = groupby(f,key=lambda x: x.isupper())
    for k, sec in grps:
        # if we hit a title line
        if k: 
            # pull all paragraphs
            v = next(grps)[1]
            # skip two empty lines after title
            next(v,""), next(v,"")

            # take all lines up to next empty line/second paragraph
            print(list(takewhile(lambda x: bool(x.strip()), v)))

Что даст вам:

['There is a vast field of fascinating human interest, lying only just outside our doors, which as yet has been but little explored. It is the Field of Animal Intelligence.\n']
['What I am trying to do here is, find the uppercase lines, and put them all in an array. Then, using the index method, I will find the first and last paragraphs of each section by comparing the indexes of these elements of this array I created.']

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

Чтобы разбить его на использование циклов:

from itertools import groupby  
from itertools import groupby
def parse_sec(bk):
    with open(bk) as f:
        grps = groupby(f, key=lambda x: bool(x.isupper()))
        for k, sec in grps:
            if k:
                print("First paragraph from section titled :{}".format(next(sec).rstrip()))
                v = next(grps)[1]
                next(v, ""),next(v,"")
                for line in v:
                    if not line.strip():
                        break
                    print(line)

Для вашего текста:

In [11]: cat -E in.txt

THE LAY OF THE LAND$
$
$
There is a vast field of fascinating human interest, lying only just outside our doors, which as yet has been but little explored. It is the Field of Animal Intelligence.$
$
Of all the kinds of interest attaching to the study of the world's wild animals, there are none that surpass the study of their minds, their morals, and the acts that they perform as the results of their mental processes.$
$
$
WILD ANIMAL TEMPERAMENT & INDIVIDUALITY$
$
$
What I am trying to do here is, find the uppercase lines, and put them all in an array. Then, using the index method, I will find the first and last paragraphs of each section by comparing the indexes of these elements of this array I created.

Знаки доллара - это новые строки, вывод:

In [12]: parse_sec("in.txt")
First paragraph from section titled :THE LAY OF THE LAND
There is a vast field of fascinating human interest, lying only just outside our doors, which as yet has been but little explored. It is the Field of Animal Intelligence.

First paragraph from section titled :WILD ANIMAL TEMPERAMENT & INDIVIDUALITY
What I am trying to do here is, find the uppercase lines, and put them all in an array. Then, using the index method, I will find the first and last paragraphs of each section by comparing the indexes of these elements of this array I created.
person Padraic Cunningham    schedule 02.01.2016
comment
Это круто, я могу видеть каждый раздел, используя этот код.. но я просто хочу увидеть их первые абзацы.. Как я могу извлечь? - person Tuğcan Demir; 03.01.2016
comment
@TuğcanDemir, что именно вы хотите извлечь из своего вопроса? - person Padraic Cunningham; 03.01.2016
comment
Вы все еще можете использовать ответ Падраика и просто удалить любую группу, состоящую только из одной строки. - person Jeffrey Swan; 03.01.2016
comment
Большое спасибо ! Но есть еще некоторые проблемы, потому что, когда я использую этот код, я снова вижу все абзацы каждого раздела. Между заголовком и первым абзацем должно быть 2 пустые строки, и я не мог это контролировать. Я не могу добавить 2 пустые строки в свой вопрос выше, веб-сайт не позволяет:/ - person Tuğcan Demir; 03.01.2016
comment
@TuğcanDemir, вам просто нужно снова позвонить next(v), чтобы пропустить вторую пустую строку - person Padraic Cunningham; 03.01.2016
comment
@TuğcanDemir, редактирование должно позаботиться о пустой строке дополнительных материалов, теперь формат должен соответствовать вашему. - person Padraic Cunningham; 03.01.2016
comment
Это сработало успешно !! Спасибо большое за вашу помощь :) - person Tuğcan Demir; 03.01.2016

Всегда есть регулярное выражение....

import re
with open("in.txt", "r") as fi:
    data = fi.read()
paras = re.findall(r"""
                   [IVXLCDM]+\n\n   # Line of Roman numeral characters
                   [^a-z]+\n\n      # Line without lower case characters
                   (.*?)\n          # First paragraph line
                   """, data, re.VERBOSE)
print "\n\n".join(paras)
person Graham    schedule 03.01.2016
comment
Это растущая форма: некоторые люди, сталкиваясь с проблемой, думают: «Я знаю, я буду использовать регулярные выражения». Теперь у них две проблемы. [IV]+ да? - person msw; 03.01.2016
comment
Как я могу напечатать первый абзац вместо первой строки? - person Tuğcan Demir; 03.01.2016
comment
так что я тоже нахожу свой код, используя ваш код .. большое спасибо :) - person Tuğcan Demir; 04.01.2016

Просмотрите код, который вы нашли, строка за строкой.

f = open("G:\\aa.txt").readlines()
flag=False
for line in f:
        if line.startswith('\n\n'):
            flag=True
        if flag:
            print(line)
        elif line.strip().endswith('\n'):
            flag=True

Кажется, он никогда не устанавливает переменную флага как истинную.

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

person st.    schedule 02.01.2016
comment
Я поделился тем же кодом, что и вы, просто установите флаг в значение true в первом блоке if. - person st.; 03.01.2016
comment
Когда я устанавливаю для первого флага значение true, он добавляет еще 2 пустые строки в каждую строку. - person Tuğcan Demir; 03.01.2016

Это должно работать, если нет абзацев со всеми заглавными буквами:

    f = open('file.txt')

    for line in f:
    line = line.strip()
    if line:  
        for c in line:
            if c < 'A' or c > 'Z': # check for non-uppercase chars
                break
        else:        # means the line is made of all caps i.e. I, II, etc, meaning new section
            f.readline()  # discard chapter headers and empty lines
            f.readline()
            f.readline()
            print(f.readline().rstrip()) # print first paragraph

    f.close()

Если вы хотите получить и последний абзац, вы можете отслеживать последнюю просмотренную строку, содержащую символы нижнего регистра, а затем, как только вы найдете всю строку верхнего регистра (I, II и т. д.), указывающую на новый раздел, вы печатаете самая последняя строка, так как это будет последний абзац в предыдущем разделе.

person SoreDakeNoKoto    schedule 02.01.2016
comment
@TuğcanDemir Я внес несколько небольших изменений, чтобы удалить пустые строки и сделать код более читабельным. Этот код (и предыдущая версия) работал с образцом, который вы предоставили выше. Можете ли вы предоставить образец раздела, который дал вам эти результаты? - person SoreDakeNoKoto; 04.01.2016

Решение TXR

$ txr firstpar.txr data
There is a vast field of fascinating human interest, lying only just outside our doors, which as yet has been but little explored. It is the Field of Animal Intelligence.
What I am trying to do here is, find the uppercase lines, and put them all in an array. Then, using the index method, I will find the first and last paragraphs of each section by comparing the indexes of these elements of this array I created.

Код в firstpar.txr:

@(repeat)
@num

@title

@firstpar
@  (require (and (< (length num) 5)
                 [some title chr-isupper]
                 (not [some title chr-islower])))
@  (do (put-line firstpar))
@(end)

По сути, мы ищем входные данные для соответствия шаблону для трехэлементного многострочного шаблона, который связывает переменные num, title и firstpar. Теперь этот шаблон как таковой может совпадать в неправильных местах, поэтому добавьте некоторые ограничивающие эвристики с утверждением require. Номер раздела должен быть короткой строкой, а строка заголовка должна содержать несколько прописных букв и не содержать строчных. Это выражение написано на TXR Lisp.

Если мы получаем совпадение с этим ограничением, мы выводим строку, захваченную в переменной firstpar.

person Kaz    schedule 04.01.2016