Есть пара вопросов с принятым ответом. Во-первых, токенизатор преобразует некоторые символы, такие как символ «в два символа` `. Во-вторых, объединение токенизированного текста обратно с пробелами не возвращает тот же результат, что и раньше. Поэтому пример текста из принятого ответа преобразует входной текст нетривиальными способами.
Однако класс CoreLabel
, который использует токенизатор, отслеживает исходные символы, с которыми они сопоставлены, поэтому тривиально восстановить правильную строку, если у вас есть оригинал.
Подход 1, представленный ниже, показывает подход с использованием принятых ответов, Подход 2 показывает мой подход, который преодолевает эти проблемы.
String paragraph = "My 1st sentence. “Does it work for questions?” My third sentence.";
List<String> sentenceList;
/* ** APPROACH 1 (BAD!) ** */
Reader reader = new StringReader(paragraph);
DocumentPreprocessor dp = new DocumentPreprocessor(reader);
sentenceList = new ArrayList<String>();
for (List<HasWord> sentence : dp) {
sentenceList.add(Sentence.listToString(sentence));
}
System.out.println(StringUtils.join(sentenceList, " _ "));
/* ** APPROACH 2 ** */
//// Tokenize
List<CoreLabel> tokens = new ArrayList<CoreLabel>();
PTBTokenizer<CoreLabel> tokenizer = new PTBTokenizer<CoreLabel>(new StringReader(paragraph), new CoreLabelTokenFactory(), "");
while (tokenizer.hasNext()) {
tokens.add(tokenizer.next());
}
//// Split sentences from tokens
List<List<CoreLabel>> sentences = new WordToSentenceProcessor<CoreLabel>().process(tokens);
//// Join back together
int end;
int start = 0;
sentenceList = new ArrayList<String>();
for (List<CoreLabel> sentence: sentences) {
end = sentence.get(sentence.size()-1).endPosition();
sentenceList.add(paragraph.substring(start, end).trim());
start = end;
}
System.out.println(StringUtils.join(sentenceList, " _ "));
Это выводит:
My 1st sentence . _ `` Does it work for questions ? '' _ My third sentence .
My 1st sentence. _ “Does it work for questions?” _ My third sentence.