嗯,这是一个有点棘手的情况,我想出了一个棘手的解决方案,但它仍然有效。我自己对 Java 很陌生,所以如果经验丰富的老手想要编辑这篇文章或对其发表评论并通过各种方式使其更加专业,请让我看起来更好。
我基本上在你已经必须检查的内容上添加了一些控制措施,看看是否存在像 Dr. Prof. Mr. Mrs. 等这样的词,如果这些词存在,它只会跳过该中断并移动到下一个中断(保持原始开始位置)寻找下一个结束(最好是不在另一位博士或先生等之后结束)
我提供了完整的程序,以便您可以看到全部内容:
import java.text.BreakIterator;
import java.util.*;
public class TestCode {
private static final String[] ABBREVIATIONS = {
"Dr." , "Prof." , "Mr." , "Mrs." , "Ms." , "Jr." , "Ph.D."
};
public static void main(String[] args) throws Exception {
String text = "Prof. Roberts and Dr. Andrews trying to solve a " +
"problem by writing a 1.200 lines of code. This will " +
"work if Mr. Java writes solid code.";
for (String s : breakSentence(text)) {
System.out.println(s);
}
}
public static List<String> breakSentence(String document) {
List<String> sentenceList = new ArrayList<String>();
BreakIterator bi = BreakIterator.getSentenceInstance(Locale.US);
bi.setText(document);
int start = bi.first();
int end = bi.next();
int tempStart = start;
while (end != BreakIterator.DONE) {
String sentence = document.substring(start, end);
if (! hasAbbreviation(sentence)) {
sentence = document.substring(tempStart, end);
tempStart = end;
sentenceList.add(sentence);
}
start = end;
end = bi.next();
}
return sentenceList;
}
private static boolean hasAbbreviation(String sentence) {
if (sentence == null || sentence.isEmpty()) {
return false;
}
for (String w : ABBREVIATIONS) {
if (sentence.contains(w)) {
return true;
}
}
return false;
}
}
这样做的目的,基本上是建立两个起点。原始起点(您使用的起点)仍然在做同样的事情,但是临时开始不会移动,除非字符串看起来准备好制成句子。就拿第一句话来说吧:
"Prof."
并检查是否由于一个奇怪的单词而中断(即,句子中是否有 Prof. Dr. 或 w/e 可能导致该中断),如果是,则 tempStart 不会移动,它会停留在那里,等待下一个块返回。在我稍微复杂一点的句子中,下一个块也有一个奇怪的单词搞乱了中断:
"Roberts and Dr."
它采用该块,因为里面有一个博士,所以它继续到第三个句子块:
"Andrews trying to solve a problem by writing a 1.200 lines of code."
一旦它到达被破坏的第三个块并且没有任何可能导致错误中断的奇怪标题,它就会从临时开始(仍在开始处)开始到当前结束,基本上将所有三个部分连接在一起。
现在它将临时开始设置为当前的“结束”并继续。
就像我说的,这可能不是一个获得你想要的东西的迷人方式,但没有其他人自愿,而且它有效shrug