2015-10-13 7 views
4

Я хотел получить даты и другие временные объекты из набора строк. Можно ли это сделать без разбора строки для дат в JAVA, поскольку большинство парсеров имеют дело с ограниченным объемом шаблонов ввода. Но ввод - это ручная запись, которая здесь и, следовательно, неоднозначна.Как получить все виды дат и временных значений из текста

Входы могут быть как:

12 сентября | середине марта | 12.September.2013

12 сентября | 12 сентября | 2013

13 сентября | 12 сентябрь | 12, февраль, 2013

Я прошел через много ответов на поиск даты в Java, но большинство из них не имеет дела с таким огромным объемом ввода узоры.

Я пробовал использовать класс SimpleDateFormat и использовать некоторые функции parse() для проверки разрывов функции разбора, что означает ее не дату. Я пробовал использовать regex, но я не уверен, подходит ли он в этом сценарии. Я также использовал ClearNLP для аннотации дат, но не дает надежного набора аннотаций.

Наиболее близким подходом к получению этих значений может быть использование Chain of responsibility, как указано ниже. Есть ли библиотека, которая имеет набор шаблонов для даты. Я могу использовать это, может быть?

+0

Где-то вы должны ограничить область действия, попробуйте обернуть ввод в свой собственный фиксированный формат. –

+0

@ ankur-singhal слишком поздно для этого приятеля Я не могу изменить эти старые данные сейчас, его уже есть, я только извлекаю – Identity1

+0

Можете ли вы предоставить некоторую информацию о том, на какие даты должны соответствовать линии? 'mid-March' немного слишком неоднозначен даже для обработки человеком. – npinti

ответ

1

Да! Я, наконец, извлекал все виды дат/временных значений, которые могут быть как общие:

середина марта | Последний месяц | 9/11

Для конкретны:

11/11/11 11:11:11

Это, наконец, произошло из-за удивительных библиотек из GATE и JAPE

Я создал более мягкое правило аннотации в JAPE, чтобы сказать «DateEnhanced», чтобы включить определенные типы дат типа «9/11 или 11th, февраль-2001» и использовал Chaining Java regex на R.H.S. из аннотаций «DateEnhanced» JAPE RULE, чтобы отфильтровать некоторые нежелательные выходы.

+0

@ ankur-singhal это было легко. – Identity1

1

Вы можете просто реализовать поддержку для все возможности шаблона, вы можете подумать о, а затем оформить документ ... ОК, это все шаблоны, поддерживаемые моим модулем. Затем вы можете бросить RuntimeException для всех других возможностей.

После этого ... итеративным способом вы можете продолжать работать над вашим модулем над входными данными и продолжать добавлять поддержку для большего количества форматов даты до тех пор, пока он не остановит повышение RuntimeException.

Я думаю, что это лучшее, что вы можете сделать здесь, если хотите сохранить его достаточно простым.

+0

Есть ли библиотека, в которой хранятся такие временные шаблоны? Какой-то справочник, кроме «ClearNLP»? – Identity1

+0

Это сработало! Используется 'GATE'. Спасибо хоть! – Identity1

0

Я могу порекомендовать вам очень хорошую реализацию вашей проблемы, unfortunetlly на польском языке: http://koziolekweb.pl/2015/04/15/throw-to-taki-inny-return/

Вы можете использовать Google Переводчик:

https://translate.google.pl/translate?sl=pl&tl=en&js=y&prev=_t&hl=en&ie=UTF-8&u=http%3A%2F%2Fkoziolekweb.pl%2F2015%2F04%2F15%2Fthrow-to-taki-inny-return&edit-text=

Код там выглядит очень красиво:

private static Date convertStringToDate(String s) {       
    if (s == null || s.trim().isEmpty()) return null;       
    ArrayList<String> patterns = Lists.newArrayList(YYYY_MM_DD_T_HH_MM_SS_SSS, 
      YYYY_MM_DD_T_HH_MM_SS            
      , YYYY_MM_DD_T_HH_MM            
      , YYYY_MM_DD);              
    for (String pattern : patterns) {           
     try {                 
      return new SimpleDateFormat(pattern).parse(s);      
     } catch (ParseException e) {           
     }                  
    }                   
    return new Date(Long.valueOf(s));           
} 
+0

Кажется, что OP не нужны только даты, но все «временные сущности», которые являются концепцией, которая требует более строгого определения IMHO. –

+0

Может 'DateFormat' матч' 12, сентябрь'. Может быть, я могу написать сложный метод, используя предложение пэтера с подходом к разряду и завоеванию. – Identity1

2

Чистый и модульный подход к этой проблеме заключается в использовании цепочки, каждый элемент цепочки пытается совместить входную строку с регулярным выражением, , если регулярное выражение соответствует входной строке, чем вы можете преобразовать входную строку в то, что может подавать SimpleDateFormat, чтобы преобразовать его в структуру данных, которую вы предпочитаете (Date? или другое временное представление, которое лучше соответствует вашим потребностям) и вернуть его, если регулярное выражение не совпадает с целым элементом, просто делегирует следующий элемент в цепочке.

Ответственность за каждый элемент цепочки состоит в том, чтобы проверить регулярное выражение на строке, дать результат или попросить следующий элемент цепи попробовать.

Цепь может быть создана и скомпонована без необходимости изменять реализацию каждого элемента цепи.

В итоге результат будет таким же, как и в ответе @KirkoR, с кодом «бит» (: D), но с модульным подходом. (Я предпочитаю регулярок подход к TRY/улова одного)

Некоторые ссылки: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

+1

Это очень актуальная вещь. Этот подход может быть очень полезным. +1 Спасибо – Identity1

+0

Наконец-то сделал. GATE потрясающе! – Identity1

0

Используйте DateNormalizer PR, или вы также можете использовать mark.util.DateParser, который, в свою очередь, используется в программе DateNormalizer PR в разработчике GATE.

+1

@ Vijay Добро пожаловать в Stack. Вы можете снять этот ответ, когда вы отправили новый ответ. – Identity1

+0

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. - [Из обзора] (/ review/low-quality-posts/10967138) – TheCodingFrog

+0

Эй, Виджай! Я заметил, что это ваш второй ответ на этот вопрос, и если вы хотите обновить или улучшить свой существующий ответ, вы всегда можете [изменить] (https://stackoverflow.com/posts/34899311/edit/9fe48992-58bb-4d5b-9768-db63f6bc9b98) ваш существующий ответ. : D – Zizouz212

0
mark.util.DateParser dp = new DateParser(); 
    ParsePositionEx parsePosition = new ParsePositionEx(0); 
    Date startDate = dp.parse("12.September.2013", parsePosition); 
    System.out.println(startDate); 

выход: чт 12 сентября 2013 17:18:18 IST

mark.util.Dateparser является частью библиотеки, которая используется DateNormalizer PR. Поэтому в файле Jape нам нужно просто импортировать его.

+0

Это можно использовать для нормализации дат. Вы можете избежать этого, если хотите только вывести даты. – Identity1

+0

Извините, я забыл ваш вопрос, говоря «без разбора». – Vijay