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

时间:2011-04-11 11:19:03

标签: c# sed nlp text-segmentation

我必须处理一个文本文件(电子书)。我想处理它,以便每行有一个句子(“换行符分隔文件”,是吗?)。如何使用sed UNIX实用程序执行此任务?它是否具有“句子边界”的符号,如“单词边界”的符号(我认为GNU版本具有该符号)。请注意,句子可以以句点,省略号,问题或感叹号结尾,最后两个组合(例如,?,!,!?,!!!!!都是有效的“句子终结符”)。输入文件的格式使得某些句子包含必须删除的换行符。

我想过像s/...|. |[!?]+ |/\n/g这样的剧本(为了更好的阅读而没有转义)。但它并没有从句子中删除换行符。

在C#中怎么样?如果我使用sed中的正则表达式会更快吗? (我想不是)。还有其他更快的方法吗?

无论哪种方式(sed或C#)都没问题。谢谢。

5 个答案:

答案 0 :(得分:3)

正则表达式是我长期使用的一个很好的选择。

对我来说非常好的正则表达式是

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

然而,正则表达式效率不高。此外,虽然逻辑适用于理想情况,但它在生产环境中效果不佳。

例如,如果我的文字是,

  

U.S.A。是一个美好的国家。大多数人都很高兴住在那里。

正则表达式方法将在每个句点分割为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项目进行令牌化,POSTag,Chuck等。

For step by step integration of SharpNLP into your C# application, read through the detailed article I have written.它将向您解释与代码段的集成。

由于

答案 1 :(得分:1)

句子分裂是一个非平凡的问题,已经开发出了机器学习算法。但是,在[.\?!]+和大写字母[A-Z]之间划分空格可能是一个很好的启发式方法。首先使用tr删除换行符,然后应用RE:

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

输出应该是每行一个句子。如果发现错误,请检查输出并优化RE。 (例如,mr. Ed将被错误地处理。也许编译这样的缩写列表。)

C#或sed是否更快只能通过实验确定。

答案 2 :(得分:0)

你可以使用这样的东西来提取句子:

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

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

答案 3 :(得分:0)

您可以查看我的教程http://code.google.com/p/graph-expression/wiki/SentenceSplitting 基本的想法是在每次拆分时都有拆分字符和不可能的前/后条件。简单的启发式工作非常好。

答案 4 :(得分:0)

您感兴趣的任务通常被称为“句子分割”。正如larsmans所说,这是一个非常重要的问题,但启发式方法通常表现得相当不错,至少对英语而言。

听起来您主要对英语感兴趣,因此已经呈现的正则表达式启发式可以充分满足您的需求。如果您想要一个更准确的解决方案(以更复杂的代价为代价),您可以考虑使用LingPipe,一个开源的NLP框架。我用LingPipe运气很好,我用过它几次。

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