将字符串拆分成句子

时间:2010-04-21 22:29:34

标签: java regex split abbreviation

我编写了这段代码,它将字符串拆分并存储在字符串数组中: -

String[] sSentence = sResult.split("[a-z]\\.\\s+");

但是,我添加了[a-z],因为我想处理一些缩写问题。但后来我的结果显示如下: -

  

此外,当埃弗雷特试图在基础数学中指导他们时,他们证明了他们的不负责任

我看到我丢失了split函数中指定的模式。我可以失去这段时间,但丢失这个词的最后一个字母会扰乱它的含义。

有人可以帮我解决这个问题,此外,有人可以帮我处理缩写吗?例如,因为我根据句点分割字符串,所以我不想丢失缩写。

4 个答案:

答案 0 :(得分:50)

解析句子远非一项微不足道的任务,即使对于像英语这样的拉丁语言也是如此。像你在问题中概述的那种天真的方法经常会失败,在实践中它将被证明是无用的。

更好的方法是使用配置了正确语言环境的BreakIterator

BreakIterator iterator = BreakIterator.getSentenceInstance(Locale.US);
String source = "This is a test. This is a T.L.A. test. Now with a Dr. in it.";
iterator.setText(source);
int start = iterator.first();
for (int end = iterator.next();
    end != BreakIterator.DONE;
    start = end, end = iterator.next()) {
  System.out.println(source.substring(start,end));
}

产生以下结果:

  1. 这是一个测试。
  2. 这是T.L.A.测试
  3. 现在有博士。

答案 1 :(得分:11)

在所有情况下都很难使正则表达式起作用,但要解决您的直接问题,您可以使用lookbehind:

String sResult = "This is a test. This is a T.L.A. test.";
String[] sSentence = sResult.split("(?<=[a-z])\\.\\s+");

结果:

This is a test
This is a T.L.A. test.

请注意,有些缩写不以大写字母结尾,例如缩写,先生等等。还有一些句子不会以句号结尾!

答案 2 :(得分:4)

如果可以,请使用自然语言处理工具,例如LingPipe。使用正则表达式很难捕捉到许多细微之处,例如(例如 :-)),先生缩写省略号(...),等等

LingPipe网站上的Sentence Detection有一个非常容易学习的教程。

答案 3 :(得分:2)

迟到的回应,但对于像我这样的未来访问者来说,经过长时间的搜索。 使用 OpenNlP 模型,这是我的最佳选择,它适用于这里的所有文本样本,包括@nbz 在评论中提到的关键文本,

My friend, Mr. Jones, has a new dog. This is a test. This is a T.L.A. test. Now with a Dr. in it."

以行间距分隔:

My friend, Mr. Jones, has a new dog.
This is a test.
This is a T.L.A. test.
Now with a Dr. in it.

您需要将 .jar 库以及经过训练的模型 en-sent.bin 导入到您的项目中。

这是一个教程,可以轻松地将您整合到快速高效的运行中:

https://www.tutorialkart.com/opennlp/sentence-detection-example-in-opennlp/

还有一个用于在 Eclipse 中进行设置:

https://www.tutorialkart.com/opennlp/how-to-setup-opennlp-java-project/

代码如下:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
 
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
 
import opennlp.tools.sentdetect.SentenceDetectorME;
import opennlp.tools.sentdetect.SentenceModel;
 
/**
* Sentence Detection Example in openNLP using Java
* @author tutorialkart
*/
public class SentenceDetectExample {
 
    public static void main(String[] args) {
        try {
            new SentenceDetectExample().sentenceDetect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * This method is used to detect sentences in a paragraph/string
     * @throws InvalidFormatException
     * @throws IOException
     */
    public void sentenceDetect() throws InvalidFormatException, IOException {
        String paragraph = "This is a statement. This is another statement. Now is an abstract word for time, that is always flying.";
 
        // refer to model file "en-sent,bin", available at link http://opennlp.sourceforge.net/models-1.5/
        InputStream is = new FileInputStream("en-sent.bin");
        SentenceModel model = new SentenceModel(is);
        
        // feed the model to SentenceDetectorME class
        SentenceDetectorME sdetector = new SentenceDetectorME(model);
        
        // detect sentences in the paragraph
        String sentences[] = sdetector.sentDetect(paragraph);
 
        // print the sentences detected, to console
        for(int i=0;i<sentences.length;i++){
            System.out.println(sentences[i]);
        }
        is.close();
    }
}

由于您实现了库,它也可以离线工作,这是一个很大的优势,因为@Julien Silland 的正确答案说这不是一个简单的过程,让训练有素的模型为您做这件事是最好的选择。