1

我正在尝试使用 Python 从文本中提取句子。文本中的每个单词都写在一行中,并带有与该单词相关的附加信息:

Mary Noun Name
loves Verb No-Name
John Noun Name
. Punct No-Name

句子边界用空行标记。我想提取包含具有某些特定特征的单词的整个句子(例如带有名称的句子)。

到目前为止,我只成功地提取了感兴趣的单词,而不是整个句子。我.readlines()习惯逐行阅读文本。然后我遍历这些行并使用 re 和.split('\t')拆分行,以便每一行都由 3 个元素的列表表示。然后我将列表中的元素与所需的值匹配,并可以提取相关的单词,但我不知道如何提取整个句子..

有人有什么建议吗?

4

4 回答 4

1

您可以用空行分隔,将类型分成一组,然后使用它 - 一个未经测试的示例......

text="""Mary Noun Name
loves Verb No-Name
John Noun Name
. Punct No-Name

John Noun Name
loves Verb No-Name
Mary Noun Name
. Punct No-Name"""

from itertools import takewhile

sentences = []
split = iter(text.splitlines())
while True:
    sentence = list(takewhile(bool, split))
    if not sentence:
        break
    types = set(el.split()[1] for el in sentence)
    words = [el.split(' ', 1)[0] for el in sentence]
    sentences.append(
        {
        'sentence': sentence,
        'types': types,
        'words': words
        }
    )


print sum(1 for el in sentences if 'Noun' in el['types']), 'sentences contain Noun'
print sentences[0]['words']
于 2012-10-15T16:40:25.107 回答
0

您可能希望将 Blender 或 Jon Clements 解决方案与存储“已解析”句子的腌制结果相结合,以便下次您可以加载该信息并更快地开始搜索。

如果您的句子列表不适合内存,则将单个句子信息按顺序存储在文件中,如果您使用二进制泡菜,则在每个泡菜句子之前存储一个长度指示符。

仅当您必须经常搜索并且解析需要大量时间(包含大量文本)时,这种额外的努力才值得。

于 2013-03-21T11:09:06.553 回答
0

我会将各个行解析为字典,您可以将其分组为由标点符号(或句点)分隔的列表。

sentences = []
columns = ('word', 'pos', 'type')

with open('file.txt', 'r') as handle:
    sentence = []

    for row in handle:
        chunks = row.split('\t')
        structure = dict(zip(columns, chunks))

        sentence.append(structure)

        if structure['pos'] == 'Punct':
            sentences.append(sentence)
            sentence = []

现在,sentences包含包含句子所有部分的列表(如果此代码有效)。

我会把它留给你来弄清楚如何做剩下的。for只需几个循环,就可以轻松找到目标句子。

要打印给定列表的句子,这样的事情应该让你开始:

print ' '.join((chunk['word'] for chunk in sentence))
于 2012-10-15T16:14:34.607 回答
0

现有的答案假设语料库足够小,可以一次性读入内存,并构建句子的数据结构,然后进行过滤。如果不是这种情况(即使现在是,将来也可能不是),您需要做某种生成器解决方案。我会看一下类似的问题:Python: How to loop through blocks of lines and see if you can make it for you.

就个人而言,我认为人们通过强制使用单一工具来为自己做更多的工作。对于一个简单的 awk 过滤器,这个特殊的问题是现成的:

awk -v RS='\n\n' -v FS='\n' -v ORS='\n\n' -v OFS='\n' '/ Name/'

当然,如果你要在 python 中做进一步的处理,这两点都不成立。

于 2012-10-15T17:07:49.393 回答