Простой синтаксический анализатор предложений Java
Есть ли простой способ создания парсера предложений в простой Java без добавления библиотек и jar-файлов?
Парсер должен не только заботиться о пробелах между словами, но и быть более умным и разбирать.!? распознавать, когда предложение заканчивается и т. д.
После синтаксического анализа в реальной базе данных или файле могут храниться только реальные слова, а не специальные символы.
спасибо большое всем заранее:)
5 ответов
Вы можете начать с просмотра класса BreakIterator.
Из JavaDoc.
Класс BreakIterator реализует методы для поиска расположения границ в тексте. Экземпляры BreakIterator поддерживают текущую позицию и сканируют текст, возвращая индекс символов, в которых встречаются границы. Внутренне BreakIterator сканирует текст с использованием CharacterIterator и, таким образом, может сканировать текст, удерживаемый любым объектом, реализующим этот протокол. StringCharacterIterator используется для проверки объектов String, переданных в setText.
Методы фабрики, предоставляемые этим классом, используются для создания экземпляров различных типов итераторов разрыва. В частности, используйте getWordIterator, getLineIterator, getSentenceIterator и getCharacterIterator для создания BreakIterator, которые выполняют анализ слов, строк, предложений и границ символов соответственно. Один BreakIterator может работать только на одном модуле (слово, строка, предложение и т. Д.). Вы должны использовать разные итераторы для каждого анализа границ объекта, который вы хотите выполнить.
Анализ границы строки определяет, где текстовая строка может быть нарушена при переносе строк. Механизм правильно обрабатывает знаки пунктуации и переносы слов.
Анализ границы предложения позволяет выбирать с правильной интерпретацией периодов в пределах чисел и сокращений, а также конечных знаков препинания, таких как кавычки и скобки.
Анализ границ слов используется функциями поиска и замены, а также в приложениях для редактирования текста, которые позволяют пользователю выбирать слова двойным щелчком мыши. Выбор слова обеспечивает правильную интерпретацию знаков препинания внутри и после слов. Символы, которые не являются частью слова, такие как символы или знаки пунктуации, имеют разрывы на обеих сторонах.
Анализ границ символов позволяет пользователям взаимодействовать с символами так, как они ожидают, например, при перемещении курсора по текстовой строке. Анализ границ символов обеспечивает правильную навигацию по символьным строкам независимо от того, как хранится символ. Например, акцентированный символ может быть сохранен как базовый символ и диакритический знак. То, что пользователи считают персонажем, может отличаться в зависимости от языка.
BreakIterator предназначен для использования только с естественными языками. Не используйте этот класс для токенизации языка программирования.
Посмотреть демо: BreakIteratorDemo.java
Основываясь на ответе @Jarrod Roberson, я создал метод util, который использует BreakIterator и возвращает список предложений.
public static List<String> tokenize(String text, String language, String country){
List<String> sentences = new ArrayList<String>();
Locale currentLocale = new Locale(language, country);
BreakIterator sentenceIterator = BreakIterator.getSentenceInstance(currentLocale);
sentenceIterator.setText(text);
int boundary = sentenceIterator.first();
int lastBoundary = 0;
while (boundary != BreakIterator.DONE) {
boundary = sentenceIterator.next();
if(boundary != BreakIterator.DONE){
sentences.add(text.substring(lastBoundary, boundary));
}
lastBoundary = boundary;
}
return sentences;
}
Просто используйте регулярное выражение (\s+
- он будет применяться к одному или нескольким пробелам (пробелам, табуляциям и т. д.), чтобы разбить String на массив.
Затем вы можете перебрать этот массив и проверить, заканчивается ли слово .?!
( String.endsWith (), чтобы найти конец предложений.
И перед сохранением любого слова используйте еще раз регулярное выражение, чтобы удалить все не алфавитно-цифровые символы.
Конечно, используйте StringTokenizer
import java.util.StringTokenizer;
public class Token {
public static void main(String[] args) {
String sentence = "Java! simple ?sentence parser.";
String separator = "!?.";
StringTokenizer st = new StringTokenizer( sentence, separator, true );
while ( st.hasMoreTokens() ) {
String token = st.nextToken();
if ( token.length() == 1 && separator.indexOf( token.charAt( 0 ) ) >= 0 ) {
System.out.println( "special char:" + token );
}
else {
System.out.println( "word :" + token );
}
}
}
}