目录 D 包含几千封 .eml 格式的电子邮件。有些电子邮件是纯文本,有些来自 Outlook,有些则有 ASCII 标题和 HTML/MIME 内容等等。存在一个字典文件 F,其中包含要在 D 目录下的文件中查找的有趣单词列表(即 red\nblue\ngreen\n...)。D目录有大量子文件夹,但除上述.eml文件外没有其他文件。应使用以下规范列出最常出现的单词:
- 对于每个有趣的单词,都应该提供有关它出现的次数和出现位置的信息。如果它在一个文件中出现多次,则应为该文件多次报告。报告发生意味着报告一个整数元组 (L,P),其中 L 是从电子邮件源顶部开始的行号,P 是该行中发生的开始位置。
这将建立一个索引来引用不同的出现和最频繁出现的有趣单词的摘要。
输出应该在单个输出文件上,并且格式没有严格定义,只要包括上述信息:有趣的词,每个有趣的词出现的次数以及它出现的位置 -> 文件/行/开始位置。
这不是一个家庭作业,而是我想对一个相当大的数据集进行实际的文本分析。我面临的挑战是选择合适的工具进行有效过滤。一种迭代方法,即单词/电子邮件/等的笛卡尔积,速度太慢,因此需要为每个文件的每一行组合多个单词过滤。
我已经尝试从有趣的单词列表 w1|w2|w3|... 中构建替代正则表达式,编译它并在每封电子邮件的每一行运行它,但它仍然很慢,尤其是当我需要检查多个在一行中出现。
例子:
电子邮件 E 有一行包含以下文本:
^ ... blah ... 红苹果 ... 蓝色蓝莓 ... 红白蓝旗。$\n
正则表达式正确报告红色(2)和蓝色(2),但在使用真正的、非常大的有趣单词词典时速度很慢。
我尝试过的另一种方法是:
使用 Sqlite 数据库在解析令牌时将令牌转储到其中,包括每个条目的(列、位置)信息,并在最后查询输出。使用适当的内存缓冲区,批量插入有很大帮助,但会增加复杂性。
我还没有尝试过数据并行化,因为我不确定令牌/解析首先是正确的做法。也许一棵字母树会更合适?
我对以下解决方案感兴趣,按优先顺序排列:
- Bash/GNU CLI 工具(尤其是通过 GNU 'parallel'可并行化的东西,仅用于 CLI 执行)
- Python(自然语言处理?)
- C/C++
不幸的是,没有 Perl,因为我不明白。