Python解析来自多个txt文件

时间:2017-04-24 20:00:52

标签: python parsing dictionary nlp

寻求如何从多个文本文件中挖掘项目以构建字典的建议。

此文字文件:https://pastebin.com/Npcp3HCM

手动转换为此必需的数据结构:https://drive.google.com/file/d/0B2AJ7rliSQubV0J2Z0d0eXF3bW8/view

有数千个这样的文本文件,它们可能有不同的章节标题,如下例所示:

  1. https://pastebin.com/wWSPGaLX
  2. https://pastebin.com/9Up4RWHu
  3. 我开始阅读文件

    from glob import glob
    
    txtPth = '../tr-txt/*.txt'
    txtFiles = glob(txtPth)
    
    with open(txtFiles[0],'r') as tf:
        allLines = [line.rstrip() for line in tf]
    
    sectionHeading = ['Corporate Participants',
                      'Conference Call Participiants',
                      'Presentation',
                      'Questions and Answers']
    
    for lineNum, line in enumerate(allLines):
        if line in sectionHeading:
            print(lineNum,allLines[lineNum])
    

    我的想法是查找段标题存在的行号,并尝试在这些行号之间提取内容,然后删除像破折号一样的分隔符。这不起作用,我试图创建这种字典,以便我以后可以在采石项目上运行各种自然语言处理算法。

    {file-name1:{
        {date-time:[string]},
        {corporate-name:[string]},
        {corporate-participants:[name1,name2,name3]},
        {call-participants:[name4,name5]},
        {section-headings:{
            {heading1:[
                {name1:[speechOrderNum, text-content]},
                {name2:[speechOrderNum, text-content]},
                {name3:[speechOrderNum, text-content]}],
            {heading2:[
                {name1:[speechOrderNum, text-content]},
                {name2:[speechOrderNum, text-content]},
                {name3:[speechOrderNum, text-content]},
                {name2:[speechOrderNum, text-content]},
                {name1:[speechOrderNum, text-content]},
                {name4:[speechOrderNum, text-content]}],
            {heading3:[text-content]},
            {heading4:[text-content]}
            }
        }
    }
    

    挑战在于不同的文件可能有不同的标题和标题数量。但总会有一个名为“演示文稿”的部分,很可能会有“问答”部分。这些章节标题总是由一串相等的符号分隔。不同说话者的内容总是用破折号串分开。 Q& A部分的“语音顺序”用方括号中的数字表示。参与者总是在文档的开头指示,在其名称前面带有星号,并且他们的图块始终在下一行。

    对于如何解析文本文件的任何建议表示赞赏。理想的帮助是提供有关如何为每个文件生成这样的字典(或其他合适的数据结构)的指导,然后可以将其写入数据库。

    由于

    - 编辑 -

    其中一个文件如下所示:https://pastebin.com/MSvmHb2e

    其中“问题与答案”部分被错误标记为“演示文稿”,并且没有其他“问题与答案”部分。

    最终示例文字:https://pastebin.com/jr9WfpV8

2 个答案:

答案 0 :(得分:8)

代码中的注释应该解释一切。如果有任何指定,请告诉我,并需要更多评论。

简而言之,我利用正则表达式找到'='分隔符行以将整个文本细分为子部分,然后为了清楚起见分别处理每种类型的部分(这样你就可以告诉我如何处理每个案例)。

旁注:我正在互换地使用'参与者'和'作者'这个词。

编辑:更新了代码,以根据演示文稿/质量保证部分中与会者/作者旁边找到的“[x]”模式进行排序。还改变了漂亮的打印部分,因为pprint不能很好地处理OrderedDict。

要删除字符串中任何位置的任何其他空格,包括Restaurant.objects.change_rating(25, name=name) ,只需执行// thin Torus = Circle in 3D Qt3DCore::QEntity *torusEntity0 = new Qt3DCore::QEntity(rootEntity); Qt3DExtras::QTorusMesh *torusMesh0 = new Qt3DExtras::QTorusMesh; torusMesh0->setRadius(15); torusMesh0->setMinorRadius(0.01f); torusMesh0->setRings(100); torusMesh0->setSlices(20); torusEntity0->addComponent(torusMesh0); torusEntity0->addComponent(material); 即可。如果您特别需要仅剥离\n,那么只需执行str.strip()

我修改了代码以删除会话中的任何空格。

\n

答案 1 :(得分:3)

您能否确认您是否只需要“演示”和“问答”部分? 此外,关于输出,可以转储类似于“手动转换”的CSV格式。

更新了适用于您提供的每个示例文件的解决方案。

根据共享的“Parsed-transcript”文件,输出来自Cell“D:H”。

#state = ["other", "head", "present", "qa", "speaker", "data"]
# codes : 0, 1, 2, 3, 4, 5
def writecell(out, data):
    out.write(data)
    out.write(",")

def readfile(fname, outname):
    initstate = 0
    f = open(fname, "r")
    out = open(outname, "w")
    head = ""
    head_written = 0
    quotes = 0
    had_speaker = 0
    for line in f:
        line = line.strip()
        if not line: continue
        if initstate in [0,5] and not any([s for s in line if "=" != s]):
            if initstate == 5:
                out.write('"')
                quotes = 0
                out.write("\n")
            initstate = 1
        elif initstate in [0,5] and not any([s for s in line if "-" != s]):
            if initstate == 5:
                out.write('"')
                quotes = 0
                out.write("\n")
                initstate = 4
        elif initstate == 1 and line == "Presentation":
            initstate = 2
            head = "Presentation"
            head_written = 0
        elif initstate == 1 and line == "Questions and Answers":
            initstate = 3
            head = "Questions and Answers"
            head_written = 0
        elif initstate == 1 and not any([s for s in line if "=" != s]):
            initstate = 0
        elif initstate in [2, 3] and not any([s for s in line if ("=" != s and "-" != s)]):
            initstate = 4
        elif initstate == 4 and '[' in line and ']' in line:
            comma = line.find(',')
            speech_st = line.find('[')
            speech_end = line.find(']')
            if speech_st == -1:
                initstate = 0
                continue
            if comma == -1:
                firm = ""
                speaker = line[:speech_st].strip()
            else:
                speaker = line[:comma].strip()
                firm = line[comma+1:speech_st].strip()
            head_written = 1
            if head_written:
                writecell(out, head)
                head_written = 0
            order = line[speech_st+1:speech_end]
            writecell(out, speaker)
            writecell(out, firm)
            writecell(out, order)
            had_speaker = 1
        elif initstate == 4 and not any([s for s in line if ("=" != s and "-" != s)]):
            if had_speaker:
                initstate = 5
                out.write('"')
                quotes = 1
            had_speaker = 0
        elif initstate == 5:
            line = line.replace('"', '""')
            out.write(line)
        elif initstate == 0:
            continue
        else:
            continue
    f.close()
    if quotes:
        out.write('"')
    out.close()

readfile("Sample1.txt", "out1.csv")
readfile("Sample2.txt", "out2.csv")
readfile("Sample3.txt", "out3.csv")

详细

在这个解决方案中有一个状态机,其工作原理如下: 1.检测是否存在标题,如果是,则写入 2.书写标题后检测扬声器 3.为该发言者写笔记 4.切换到下一个扬声器等等......

您可以根据需要稍后处理csv文件。 您也可以在完成基本处理后以任何格式填充数据。

修改

请更换“writecell”功能

def writecell(out, data):
    data = data.replace('"', '""')
    out.write('"')
    out.write(data)
    out.write('"')
    out.write(",")