Как определить дату из строки в Java
Недавно меня бросает вызов довольно "легкой" проблемой. Предположим, что есть предложения (сохраненные в String), и мне нужно выяснить, существует ли какая-либо дата в этой строке. Проблемы заключаются в том, что дата может быть в разных форматах. Некоторые примеры показаны в списке:
- 12 июня 1956 года
- Лондон, 21 октября 2014 года.
- 13 октября 1999 г.
- 01/11/2003
Стоит упомянуть, что они содержатся в одной строке. Так что в качестве примера это может быть как:
String s = "This event took place on 13 October 1999.";
Мой вопрос в этом случае был бы тем, как я могу обнаружить, что в этой строке есть дата. Мой первый подход состоял в том, чтобы найти слово "событие", а затем попытаться локализовать дату. Но с более и более возможными форматами даты это решение не очень красиво. Второе решение, которое я пробовал, - создать список в течение нескольких месяцев и выполнить поиск. Это имело хорошие результаты, но по-прежнему не учитывает случаи, когда дата выражается всеми цифрами.
Одним из решений, которое я до сих пор не пробовал, является создание регулярных выражений и попытка найти совпадение в строке. Не уверен, насколько это решение может снизить производительность.
Что может быть хорошим решением, которое я, вероятно, должен рассмотреть? Кто-нибудь сталкивался с подобной проблемой раньше и какие решения вы нашли?
Одно можно сказать наверняка, что нет времени, поэтому единственной интересной частью является дата.
Ответы
Ответ 1
Использование библиотеки natty.joestelmach.com
Natty - это парсер с естественным языком, написанный на Java. Учитывая выражение даты, natty будет применять стандартные методы распознавания языка и перевода для составления списка соответствующих дат с необязательной информацией синтаксиса и синтаксиса.
import com.joestelmach.natty.*;
List<Date> dates =new Parser().parse("Start date 11/30/2013 , end date Friday, Sept. 7, 2013").get(0).getDates();
System.out.println(dates.get(0));
System.out.println(dates.get(1));
//output:
//Sat Nov 30 11:14:30 BDT 2013
//Sat Sep 07 11:14:30 BDT 2013
Ответ 2
Вы после Именованное распознавание сущностей. Я бы начал с Stanford NLP. Модель 7-го класса включает дату, но онлайн-демонстрация и пропускает "13".: (
Natty, упомянутый выше, дает лучший ответ.
Ответ 3
Если это только одна строка, вы можете использовать регулярное выражение, как вы упомянули. Необходимо найти разные выражения формата даты. Вот некоторые примеры:
Регулярные выражения - даты
Если это документ или большой текст, вам понадобится парсер. Вы можете использовать Лексический анализ.
В зависимости от проекта, использующего внешнюю библиотеку, как упомянуто в некоторых ответах, может быть хорошей идеей. Иногда это не вариант.
Ответ 4
Я сделал это раньше с хорошими precision
и recall
. Вам понадобится GATE и его плагин ANNIE
.
-
Используйте инструмент инструмента GATE для создания файла .GAPP
, который будет содержать ваши
processing resources
.
-
Используйте файл .GAPP
для использования извлеченного Date
набор аннотаций.
Шаг 2 можно сделать следующим образом:
Corpus corpus = Factory.newCorpus("Gate Corpus");
Document gateDoc = Factory.newDocument("This event took place on 13 October 1999.");
corpus.add(gateDoc);
File pluginsHome = Gate.getPluginsHome();
File ANNIEPlugin = new File(pluginsHome, "ANNIE");
File AnnieGapp = new File(ANNIEPlugin, "Test.gapp");
AnnieController =(CorpusController) PersistenceManager.loadObjectFromFile(AnnieGapp);
AnnieController.setCorpus(corpus);
AnnieController.execute();
Позже вы можете увидеть извлеченные аннотации следующим образом:
AnnotationSetImpl ann = (AnnotationSetImpl) gateDoc.getAnnotations();
System.out.println("Found annotations of the following types: "+ gateDoc.getAnnotations().getAllTypes());
Я уверен, что вы можете сделать это легко с помощью встроенного набора аннотаций Date
. Он также очень полезен.
Чтобы увеличить набор аннотаций Date
, создайте правило аннотации lenient в JAPE скажите 'DateEnhanced' из встроенной аннотации ANNIE Date
включить определенные типы дат типа "9/11" и использовать регулярное выражение "Цепочка Java" на RHS аннотаций "DateEnhanced" JAPE RULE, чтобы отфильтровать некоторые нежелательные выходы (если есть).