Есть ли существующее решение для динамического создания регулярных выражений из заданного шаблона формата даты и времени? Поддерживаемый шаблон формата даты и времени не имеет значения (Joda DateTimeFormat, java.text.SimpleDateTimeFormat или другие).
В качестве конкретного примера, для заданного формата даты и времени, такого как dd/MM/yyyy hh:mm, он должен сгенерировать соответствующее регулярное выражение, чтобы соответствовать дате и времени в указанных форматах.





SimpleDateFormat уже делает это с помощью метода parse().
Если вам нужно проанализировать несколько дат из одной строки, начните с регулярного выражения (даже если оно слишком мягко совпадает) и используйте parse() для всех потенциальных совпадений, найденных регулярным выражением.
Это может быть неразрешимым. Что делать, если в тексте есть две даты, например «Между A и B, мля», где A и B - даты ...
Что ж, тогда они будут найдены как две группы, как и при поиске регулярного выражения.
Если вы ищете базовую проверку даты, этот код соответствует этим данным.
\b(0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012])[- /.](19|20)?[0-9]{2}\b
10/07/2008
10.07.2008
1-01/2008
10/07/08
10.07.2008
1-01/08
Код через регулярное выражение
мне нужен генератор регулярных выражений для данного DateTimeFormat. Я не знаю формат даты, используемый в данном корпусе. Итак, пользователь сначала должен предоставить, сказав sth, например DDMM hh: mm, и я нахожу эти значения даты в тексте. Я создал что-то с помощью JFlex. Я также выложу это здесь после того, как почищу.
Я предполагаю, что у вас есть ограниченный алфавит, из которого могут быть построены ваши форматы времени. Это означает, что "HH" всегда будет «часами» в 24-часовом формате, "dd" всегда будет днем с нулем в начале и так далее.
Из-за последовательной природы формата времени вы можете попытаться токенизировать строку формата "dd/mm/yyyy HH:nn" в массив ["dd", "/", "mm", "/", "yyyy", " ", "HH", ":", "nn"]. Затем сформируйте строку шаблона из этого массива, заменив "HH" на "([01][0-9]|2[0-3])" и так далее. Предварительно сконструируйте эти атомы шаблона в поисковую таблицу / массив. Все части вашего массива, которых нет в таблице поиска, являются литералами. Избегайте их в соответствии с правилами регулярных выражений и добавьте их в строку шаблона.
Обновлено: в качестве побочного эффекта для решения на основе регулярных выражений, когда вы помещаете все «атомы» регулярных выражений в свою таблицу поиска в скобки и отслеживаете их порядок в заданной строке формата, вы сможете использовать вспомогательные совпадения для извлечения необходимые компоненты из совпадения и передать их в функцию CreateDate, таким образом полностью пропуская часть ParseDate.
Это прилично работает, но в большей степени ориентировано на английский язык. Тогда "ddd" может быть сопоставлено с (пн | вт | ср | чт | пт | сб | вс), но вам потребуется отображение, зависящее от локали. Становится хуже, когда формат даты генерирует цифры, отличные от ASCII. Более подробную информацию об i18n можно найти в блоге М.Каплана.
Да, это именно то, что мне нужно. Я подумал сделать что-то подобное, так как не смог найти ничего, что уже существует. Для разбора dateTimeFormat я использовал jflex. Таким образом, если это "d", оно должно соответствовать 1 или 2 цифрам, или если это "ddd", оно должно соответствовать 3 цифрам и т. д. Однако мне все еще нужно улучшить его для i18n.
@MSalters. Не могли бы вы дать ссылку на упомянутый вами блог? Спасибо
Для шаблонов, зависящих от языкового стандарта, вы можете абстрагироваться от этого и построить таблицу поиска из функций даты локали вашего языка. Предварительное знание языка, на котором проводятся свидания, конечно, требуется, но тогда это довольно просто.
Имейте в виду, что «дд» для «2 цифр» приведет к ложным срабатываниям. «99» будет соответствовать, но, конечно же, недопустимо в качестве компонента даты, кроме «двузначного года».
Да, это очевидно, мне просто не хватило символов, чтобы объяснить более подробно при добавлении комментария. Реальная нагрузка заключается в том, как MSalters сказал, что цифры, отличные от ASCII, такие как японские и арабские числа. Я думаю, что для каждого типа наборов цифр следует создавать разные регулярные выражения.
Конечно. Как я уже сказал, я думаю, что вы можете извлечь большинство из них из функций даты, специфичных для локали, на выбранном вами языке программирования, и некоторые из них могут потребовать ручной работы, если вы знаете, что делаете. I18N - это сложно, если брать на максимум.
Приведенный ниже код js / jQuery предназначен для динамически сгенерированного RegEx только для формата даты, а не для DateTime (версия для разработки еще не полностью протестирована).
Формат даты должен быть в "Д М Г".
Например.
- DD-MM-YY
- DD-MM-YYYY
- YYYY-MM-DD
- YYYY-DD-MM
- MM-DD-YYYY
- MM-DD-YY
- DD/MM/YY
- DD/MM/YYYY
- YYYY/MM/DD
- YYYY/DD/MM
- MM/DD/YYYY
- MM/DD/YY
Или другие форматы, но созданные с использованием символов «Д М Г»:
var dateFormat = "DD-MM-YYYY";
var order = [];
var position = {"D":dateFormat.search('D'),"M":dateFormat.search('M'),"Y":dateFormat.search('Y')};
var count = {"D":dateFormat.split("D").length - 1,"M":dateFormat.split("M").length - 1,"Y":dateFormat.split("Y").length - 1};
var seprator ='';
for(var i=0; i<dateFormat.length; i++){
if (["Y","M","D"].indexOf(dateFormat.charAt(i))<0){
seprator = dateFormat.charAt(i);
}else{
if (order.indexOf(dateFormat.charAt(i)) <0 ){
order.push(dateFormat.charAt(i));
}
}
}
var regEx = "^";
$(order).each(function(ok,ov){
regEx += '(\d{'+count[ov]+'})'+seprator;
});
regEx = regEx.substr(0,(regEx.length)-1);
regEx + = "$";
var re = new RegExp(regEx);
console.info(re);
ПРИМЕЧАНИЕ. Проверки по месяцам / дням не проводятся.
например месяц должен быть в 01-12 или дата должна быть в 01-31
он анализирует, только если данный текст соответствует шаблону, и возвращает объектное представление Date этой строки. Он не анализирует, находится ли информация о дате где-то в других текстах. вроде "sometext 12/03/2004 sometext.