【问题标题】:Python text extractionPython文本提取
【发布时间】:2019-02-04 16:26:03
【问题描述】:

我正在使用 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”,并且不包括其他名称,与 Title 等相同。

我的输出如下:

Chen, G. 性状关系检验,2000,doi.dx.10.1037//0021-9010.85.6.835

期望的输出应该是:

Chen, G., Gully, SM., Whiteman, JA., Kilcullen, RN., 2000,特质类个体差异、状态类个体差异和学习表现之间关系的检验,doi.dx.10.1037 //0021-9010.85.6.835

但提取只包括每一行的第一行——

有什么建议吗?

【问题讨论】:

  • 您能否让您的示例文件更简洁一些,并具体说明您的预期输出应该是什么?
  • 示例文件是从搜索引擎提取的.txt,它从文章中提取数据。期望的输出应该是:Chen, G., Gully, SM., Whiteman, JA., Kilcullen, RN., 2000, 检查特征样个体差异、状态样个体差异和学习表现之间的关系,@987654321 @,但提取只包括每一行的第一行
  • 我明白了,但我们很难用肉眼来解析它。如果您可以为我们简化它,并将“yadayada”替换为真实的预期输出,那就太好了。
  • 抱歉,按输入太早了:)

标签: python string extraction


【解决方案1】:

您需要在解析文件时跟踪您所在的部分。编写状态机有更简洁的方法,但作为一个快速简单的示例,您可以执行以下操作。

基本上,将每个部分的所有行添加到该部分的列表中,然后合并列表并在最后执行任何操作。请注意,我没有对此进行测试,只是为了向您展示总体思路。

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

【讨论】:

  • 使用此代码输出为空atm,似乎无法在txt文件中搜索以“AU”开头的行
  • 部分检查需要是“部分不是无”。我更新了它,但正如我在描述中所述,它旨在作为伪代码为您提供总体思路。您将需要适应以完全实施您的案例。
【解决方案2】:

初步了解

根据你的例子,我认为:

  • 文本以行提供。
  • 示例文本似乎有太多换行符,可能是它从 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)

【讨论】:

  • 就我在编码和python语言方面的小知识而言,这对我来说是正确的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多