27

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

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

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

此外,当埃弗里特试图教他们基础数学时,他们被证明反应迟钝

我看到我丢失了 split 函数中指定的模式。我可以丢掉句号,但是丢掉单词的最后一个字母会扰乱它的意思。

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

4

4 回答 4

58

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

更好的方法是使用配置了正确语言环境的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. 这是一个 TLA 测试。
  3. 现在有一个博士在里面。
于 2010-04-22T02:42:36.537 回答
12

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

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.

注意有不以大写字母结尾的缩写,如abbrev.、Mr.等……还有不以句点结尾的句子!

于 2010-04-21T22:32:19.813 回答
4

如果可以,请使用自然语言处理工具,例如LingPipe。使用正则表达式很难捕捉到许多细微之处,例如 ( eg :-))、Mr.abbreviationsellipsis (...)等等

LingPipe 网站上有一个非常容易理解的关于句子检测的教程。

于 2010-04-21T22:43:55.630 回答
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 的正确答案说这不是一个直接的过程,让一个训练有素的模型为您做这件事是最好的选择。

于 2021-01-22T13:50:14.627 回答