Извлечение текста на Python - PullRequest
0 голосов
/ 04 февраля 2019

Я работаю над извлечением текста с помощью Python.Вывод не так желателен как я хочу!

У меня есть текстовый файл, содержащий такую ​​информацию:

FN Clarivate Analytics Web of Science
VR 1.0

PT J

AU Chen, G

   Gully, SM

   Whiteman, JA

   Kilcullen, RN

AF Chen, G

   Gully, SM

   Whiteman, JA

   Kilcullen, RN

TI Examination of relationships among trait-like individual differences,

   state-like individual differences, and learning performance

SO JOURNAL OF APPLIED PSYCHOLOGY

CT 13th Annual Conference of the

   Society-for-Industrial-and-Organizational-Psychology

CY APR 24-26, 1998

CL DALLAS, TEXAS

SP Soc Ind & Org Psychol

RI Gully, Stanley/D-1302-2012

OI Gully, Stanley/0000-0003-4037-3883

SN 0021-9010

PD DEC

PY 2000

VL 85

IS 6

BP 835

EP 847

DI 10.1037//0021-9010.85.6.835

UT WOS:000165745400001

PM 11125649

ER

, и когда я использую свой код, подобный этому

import random
import sys

filepath = "data\jap_2000-2001-plain.txt"

with open(filepath) as f:
    articles = f.read().strip().split("\n")

articles_list = []

author = ""
title = ""
year = ""
doi = ""

for article in articles:
    if "AU" in article:
        author = article.split("#")[-1]
    if "TI" in article:
        title = article.split("#")[-1]
    if "PY" in article:
        year = article.split("#")[-1]
    if "DI" in article:
        doi = article.split("#")[-1]
    if article == "ER#":
        articles_list.append("{}, {}, {}, https://doi.org/{}".format(author, title, year, doi))
print("Oh hello sir, how many articles do you like to get?")
amount = input()

random_articles = random.sample(articles_list, k = int(amount))


for i in random_articles:
    print(i)
    print("\n")

exit = input('Please enter exit to exit: \n')
if exit in ['exit','Exit']:
    print("Goodbye sir!")
    sys.exit()

Извлечение не включает данные, которые имеютбыло введено после перевода строки, если я запустил этот код, вывод будет выглядеть как «AU Chen, G» и не включает другие имена, то же самое с заголовком и т. д. и т. д.

Мой вывод выглядит так:

Чен, Г. Исследование взаимосвязи между чертами, 2000, doi.dx.10.1037 // 0021-9010.85.6.835

Желаемый результат должен быть:

Чен, Г., Gully, SM., Whiteman, JA., Kilcullen, RN., 2000, Исследование взаимосвязей между индивидуальными различиями, подобными состоянию, индивидуальными различиями в состоянии и успеваемостью, doi.dx.10.1037 // 0021-9010.85.6.835

но извлечение включает только первый ряд каждой строки -

Есть предложения?

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Первоначальное понимание

Исходя из вашего примера, я считаю, что:

  • Текст представлен в строках.
  • В тексте примера слишком много новых строк, возможно, это артефакт его переноса из DOS / Windows?Если это так, то требуется либо обработка CRLF, либо альтернативные строки должны игнорироваться.
  • строки разделены на секции.
  • Каждая раздел ограничен двухбуквенным тегом в верхнем регистре в столбцах 0,1 в первой строке в разделе , и продолжается до началановой секции .
  • Каждая строка имеет либо тег , либо 2 пробела, за которыми следует пробел в столбцах 0-2.
  • Искусственный раздел , ограниченный тегом ER, обозначает конец записи .
  • ER раздел не содержит используемого текста.

Может также случиться так, что:

  • Записи начинаются с тега FN,
  • Любой текст, встречающийся за пределами пары FN / ER, можно игнорировать.

Предлагаемый дизайн

Если это так, я рекомендуюВы пишете текстовый процессор, используя эту логику:

  • Чтение строк.
  • Обработка CR / LF-обработки;или пропустить альтернативные строки;или «не волнуйтесь, в реальном тексте нет этих разрывов строк»?
  • Использовать конечный автомат с неизвестным числом состояний, начальное состояние - ER.
  • Специальныйправило: игнорировать текст в состоянии ER, пока не встретится строка FN.
  • Общее правило: когда тег виден, завершите предыдущее состояние и начните новое состояние, названное в честь увиденного тега.Любой накопленный текст добавляется в запись.
  • Если тег не виден, накапливайте текст в предыдущем теге.
  • Специальное правило: при входе в состояние ER добавьте накопленную записьк списку накопленных записей.

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

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

from warnings import warn

Debug = True

def read_lines_from(file):
    """Read and split lines from file. This is a separate function, instead
       of just using file.readlines(), in case extra work is needed like
       dos-to-unix conversion inside a unix environment.
    """
    with open(file) as f:
        text = f.read()
        lines = text.split('\n')

    return lines

def parse_file(file):
    """Parse file in format given by 
        https://stackoverflow.com/questions/54520331
    """
    lines = read_lines_from(file)
    state = 'ER'
    records = []
    current = None

    for line_no, line in enumerate(lines):
        tag, rest = line[:2], line[3:]

        if Debug:
            print(F"State: {state}, Tag: {tag}, Rest: {rest}")

        # Skip empty lines
        if tag == '':
            if Debug:
                print(F"Skip empty line at {line_no}")
            continue

        if tag == '  ':
            # Append text, except in ER state.
            if state != 'ER':
                if Debug:
                    print(F"Append text to {state}: {rest}")
                current[state].append(rest)
            continue

        # Found a tag. Process it.

        if tag == 'ER':
            if Debug:
                print("Tag 'ER'. Completed record:")
                print(current)

            records.append(current)
            current = None
            state = tag
            continue

        if tag == 'FN':
            if state != 'ER':
                warn(F"Found 'FN' tag without previous 'ER' at line {line_no}")
                if len(current.keys()):
                    warn(F"Previous record (FN:{current['FN']}) discarded.")

            if Debug:
                print("Tag 'FN'. Create empty record.")

            current = {}

        # All tags except ER get this:
        if Debug:
            print(F"Tag '{tag}'. Create list with rest: {rest}")

        current[tag] = [rest]
        state = tag

    return records

if __name__ == '__main__':
    records = parse_file('input.txt')
    print('Records =', records)
0 голосов
/ 04 февраля 2019

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

В основном, добавьте все строки для каждого раздела в список для этого раздела, а затем объединитесписки и делать что угодно в конце.Обратите внимание, я не проверял это, просто псевдо-кодирование, чтобы показать вам общую идею.

authors = []
title = []
section = None

for line in articles:
    line = line.strip()

    # Check for start of new section, select the right list to add to
    if line.startswith("AU"):
        line = line[3:]
        section = authors
    elif line.startswith("TI"):
        line = line[3:]
        section = title
    # Other sections..
    ...

    # Add line to the current section
    if line and section is not None:
        section.append(line)

authors_str = ', '.join(authors)
title_str = ' '.join(title)
print authors_str, title_str
...