在句子边界处分割文本文件

本文关键字:分割文本 文件 边界 句子 | 更新日期: 2023-09-27 17:49:35

我必须处理一个文本文件(电子书)。我想把它处理成每行一个句子("换行分隔文件",对吧?)我该如何使用UNIX实用工具来完成这项任务?它是否像"词边界"一样有"句子边界"的符号(我认为GNU版本有)?请注意,句子可以以句号、省略号、问号或感叹号结尾,最后两个可以组合在一起(例如?,!,!?), ! !都是有效的"句子终止符")。输入文件的格式使某些句子包含必须删除的换行符。

我考虑过像s/...|. |[!?]+ |/'n/g这样的脚本(为了更好地阅读而未转义)。但它不会从句子中删除换行符。

在c#中呢?如果我像在sed中那样使用正则表达式,会不会快得多?(我不这么认为)。有其他更快的方法吗?

两种方法(sed或c#)都可以。谢谢你。

在句子边界处分割文本文件

Regex是一个很好的选择,我使用了很长一段时间。

一个非常好的正则表达式是

 string[] sentences = Regex.Split(sentence, @"(?<=['""A-Za-z0-9]['.'!'?])'s+(?=[A-Z])");

然而,正则表达式效率不高。此外,尽管逻辑在理想情况下工作,但在生产环境中却不能很好地工作。

例如,如果我的文本是

。是一个很棒的国家。大多数人觉得住在那里很快乐。

regex方法将通过在每个句点拆分将其分类为5个句子。但是我们知道逻辑上它应该被分成两个句子。

这就是我寻找机器学习技术的原因,最后SharpNLP对我来说工作得很好。

 private string mModelPath = @"C:'Users'ATS'Documents'Visual Studio 2012'Projects'Google_page_speed_json'Google_page_speed_json'bin'Release'";
 private OpenNLP.Tools.SentenceDetect.MaximumEntropySentenceDetector mSentenceDetector;
 private string[] SplitSentences(string paragraph)
    {
        if (mSentenceDetector == null)
        {
            mSentenceDetector = new OpenNLP.Tools.SentenceDetect.EnglishMaximumEntropySentenceDetector(mModelPath + "EnglishSD.nbin");
        }
        return mSentenceDetector.SentenceDetect(paragraph);
    }

在这个例子中,我使用了SharpNLP,其中我使用了EnglishSD。Nbin——一个预先训练的句子检测模型。

现在,如果我在这个方法上应用相同的输入,它将完美地将文本分割成两个逻辑句子。

您甚至可以使用SharpNLP项目标记,posttag, Chuck等。

要逐步将SharpNLP集成到您的c#应用程序中,请阅读我写的详细文章。它将向您解释与代码片段的集成。

谢谢

分句是一个非常重要的问题,机器学习算法已经被开发出来。但是在[.'?!]+和大写字母[A-Z]之间分割空格可能是一个很好的启发式方法。先用tr删除换行符,然后应用RE:

tr ''r'n' ' ' | sed 's/'([.?!]')'s's*'([A-Z]')/'1'n'2/g'

输出应该每行一个句子。如果发现错误,检查输出并改进正则。(例如,mr. Ed将被错误地处理。也许可以把这些缩写列一个清单

c#和sed哪个更快,只能通过实验来确定。

您可以使用如下命令提取句子:

var sentences = Regex.Matches(input, @"['w ,]+['.!?]+")
foreach (Match match in sentences)
{
  Console.WriteLine(match.Value);
}

这应该匹配包含单词、空格和逗号,并以(任意数量的)句号、感叹号和问号结尾的句子。

您可以查看我的教程http://code.google.com/p/graph-expression/wiki/SentenceSplitting基本的想法是在每次分割时有分割字符和不可能的前置/后置条件。

你感兴趣的任务通常被称为"句子分割"。正如larsmans所说,这是一个不平凡的问题,但启发式方法通常表现得相当好,至少对于英语。

听起来您主要对英语感兴趣,因此已经提出的正则表达式启发式可能足以满足您的需求。如果您想要一个更精确的解决方案(代价是稍微复杂一点),您可以考虑使用LingPipe,这是一个开源的NLP框架。我用过几次LingPipe,运气还不错。

请参阅http://alias-i.com/lingpipe/demos/tutorial/sentences/read-me.html获取有关句子切分的详细教程。