寻求如何从多个文本文件中挖掘项目以构建字典的建议。
此文字文件:https://pastebin.com/Npcp3HCM
手动转换为此必需的数据结构:https://drive.google.com/file/d/0B2AJ7rliSQubV0J2Z0d0eXF3bW8/view
有数千个这样的文本文件,它们可能有不同的章节标题,如下例所示:
我开始阅读文件
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
其中“问题与答案”部分被错误标记为“演示文稿”,并且没有其他“问题与答案”部分。
答案 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格式。
更新了适用于您提供的每个示例文件的解决方案。
#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(",")