Как разобрать текст на предложения

Я пытаюсь разбить абзац на предложения. Вот мой код:

import java.util.*;

public class StringSplit {
 public static void main(String args[]) throws Exception{
     String testString = "The outcome of the negotiations is vital, because the current tax levels signed into law by President George W. Bush expire on Dec. 31. Unless Congress acts, tax rates on virtually all Americans who pay income taxes will rise on Jan. 1. That could affect economic growth and even holiday sales.";
     String[] sentences = testString.split("[\\.\\!\\?]");
     for (int i=0;i<sentences.length;i++){  
         System.out.println(i);
      System.out.println(sentences[i]);  
     }  
 }
}

Были обнаружены две проблемы:

  1. Код разбивается всякий раз, когда встречается символ точки (""."), даже если на самом деле это одно предложение. Как предотвратить это?
  2. Каждое разделенное предложение начинается с пробела. Как удалить лишнее пространство?

person user533203    schedule 07.12.2010    source источник


Ответы (7)


Проблема, о которой вы упомянули, является проблемой НЛП (обработка естественного языка). Можно написать грубый механизм правил, но он может не масштабироваться для поддержки полного английского текста.

Чтобы получить более глубокое представление и библиотеку Java, перейдите по этой ссылке http://nlp.stanford.edu/software/lex-parser.shtml , http://nlp.stanford.edu:8080/parser/index.jsp и аналогичный вопрос для ruby языка Как разбить абзац текста на предложения? (желательно на Ruby)

например: Текст -

Исход переговоров жизненно важен, потому что нынешние уровни налогов, подписанные президентом Джорджем Бушем, истекают 31 декабря. Если Конгресс не примет решения, налоговые ставки практически для всех американцев, которые платят подоходный налог, вырастут 1 января. может повлиять на экономический рост и даже праздничные продажи.

после тегирования становится:

/DT исход/NN/В/DT переговоров/NNS является/VBZ жизненно важным/JJ ,/, потому что/IN/DT текущего/JJ налоговых/NN уровней/NNS подписано/VBN в/В законе/NN by/ В Президент/ННП Джордж/ННП У./ННП Буш/ННП истекает/ВБП на/РП Дек./ННП 31/КД ./. Если только /В Конгрессе/ННП действует/ВБЗ ,/, налог/НН ставки/ННС на/В практически/РБ все/РБ американцы/ННПС кто/ВП платит/ВБП доход/НН налоги/ННС будет/МД поднимется/ВБ на/ В янв./ННП 1/КД ./. Это/DT может/MD повлиять/VB экономический/JJ рост/NN и/CC даже/RB праздник/NN продаж/NNS ./. Разобрать

Проверьте, как он различает точку (.) и период после 31 декабря...

person Favonius    schedule 07.12.2010

Вы можете попробовать использовать класс java.text.BreakIterator для разбора предложений. Например:

BreakIterator border = BreakIterator.getSentenceInstance(Locale.US);
border.setText(text);
int start = border.first();
//iterate, creating sentences out of all the Strings between the given boundaries
for (int end = border.next(); end != BreakIterator.DONE; start = end, end = border.next()) {
    System.out.println(text.substring(start,end));
}
person Jay Weinberg    schedule 01.08.2013
comment
BreakIterator — хорошая идея, но она страдает от многих подобных проблем. См. этот вопрос: stackoverflow.com/questions/17159513/ - person james.garriss; 11.01.2016

Первую довольно сложно решить правильно, так как вам придется реализовать обнаружение предложений. Я предлагаю вам не делать этого и просто разделять предложения двумя пустыми строками после знака препинания. Например:

"The outcome of the negotiations is vital, because the current tax levels signed into law by President George W. Bush expire on Dec. 31.  Unless Congress acts, tax rates on virtually all Americans who pay income taxes will rise on Jan. 1.  That could affect economic growth and even holiday sales."

Второе можно решить с помощью String.trim().

Пример:

String one = "   and now...    ";
String two = one.trim();
System.out.println(two);          // output: "and now..."
person darioo    schedule 07.12.2010
comment
Проблема с вашим первым решением заключается в том, что за последнее десятилетие или около того произошел переход от вставки двух пробелов между предложениями к вставке только одного. Для письма, выполненного в этом новом стиле, ваше решение не сработает. :( - person james.garriss; 11.01.2016

Обрезать Это...

person Eternal Noob    schedule 07.12.2010

Учитывая текущий формат ввода, будет сложно разбить на предложения. Вы должны ввести какое-то правило, дополнительное правило для определения конца предложения, помимо точки. Например, это правило может быть таким: «предложение должно заканчиваться точкой (.) и двумя пробелами». (Вот как инструмент UNIX grep идентифицирует предложения.

person Vijay Mathew    schedule 07.12.2010

Вы можете использовать класс SentenceSplitter, предоставленный этой библиотекой с открытым исходным кодом здесь.

SentenceSplitter sp = new SentenceSplitter("filename");
String str = null;
while((str = sp.next().toString()) != null)
{
    //Your code here.
}
person Pooja N Babu    schedule 22.02.2015
comment
По этому URL нечего скачивать. Он возвращает У вас нет разрешения на доступ к /page/download_view/ на этом сервере. - person james.garriss; 11.01.2016

сначала Trim() Your String... и используйте эту ссылку

http://www.java-examples.com/java-string-split-example &http://www.rgagnon.com/javadetails/java-0438.html

и вы также можете использовать класс StringBuffer... просто используйте эту ссылку, надеюсь, она вам поможет

person Jimit Tank    schedule 07.12.2010