“Умный” (прощающий) синтаксический анализатор даты?

На самом деле, вопреки взаимопониманию Монад, они не имеют никакого отношения к состоянию. Монады являются просто путем к переносящимся вещам и предоставляют методы, чтобы сделать операции на обернутом материале, не разворачивая его.

, Например, можно создать тип для обертывания другого в Haskell:

data Wrapped a = Wrap a

Для обертывания материала мы определяем

return :: a -> Wrapped a
return x = Wrap x

, Чтобы выполнить операции без разворачивания, сказать, что у Вас есть функция f :: a -> b, тогда можно сделать это к [1 115] лифт что функция для действия на обернутые значения:

fmap :: (a -> b) -> (Wrapped a -> Wrapped b)
fmap f (Wrap x) = Wrap (f x)

Это обо всех, там должен понять. Однако оказывается, что существует более общая функция, чтобы сделать этот подъем , который является bind:

bind :: (a -> Wrapped b) -> (Wrapped a -> Wrapped b)
bind f (Wrap x) = f x

bind может сделать [больше чем 117], но не наоборот. На самом деле, fmap может быть определен только с точки зрения bind и return. Так, при определении монады.. Вы даете его тип (здесь, это было Wrapped a), и затем скажите, как его return и bind операции работают.

прохладная вещь состоит в том, что это оказывается таким общим шаблоном, что он открывается повсеместно, инкапсулирование состояния чистым способом является только одним из них.

Для хорошей статьи о то, как монады могут использоваться, чтобы представить функциональные зависимости и таким образом управлять порядком оценки, как он, используется в монаде Haskell IO, проверьте IO В .

Что касается понимания монад, не волнуйтесь слишком много об этом. Считайте о них, что Вы находите интересными и не волнуете, не понимаете ли Вы сразу же. Тогда просто дайвинг на языке как Haskell является способом пойти. Монады являются одной из этих вещей, где, понимая струйки в Ваш мозг практикой, однажды Вы просто внезапно понимаете понимание их.

5
задан bluish 23 December 2011 в 08:37
поделиться

5 ответов

Я наконец извлек тестовый набор из более чем 200 примеров дат, которые действительно встречаются в наборе данных. Некоторые плохо себя ведут, некоторые совсем больны (например, «01010»).

Я перепробовал все существующие модули Perl, которые смог найти, но вероятность успеха была слишком низкой. В конце концов я заново изобрел свое колесо, добившись более 98% успеха.

Мой алгоритм представляет собой последовательность все более нечетких распознавателей, начиная с жестко действительных дат до общей территории предположений. Побеждает тот, кто первым вернет результат "успех". В середине этого стека у меня есть «главный» распознаватель, который делает что-то вроде этого:

  • анализирует наборы чисел в строке в любом месте. Также распознаются «названия месяцев» на французском и английском языках.

  • Для каждого из них я разделил их на три корзины: кандидаты на год, кандидаты на месяц, кандидаты на день. Например, «13» будет в сегменте «возможный год» и в сегменте «возможный день». «Февраль», конечно, уйдет только в «месячное» ведро. В каждом сегменте значение помечено «уровнем правдоподобия» - произвольным числом, которое зависит от ряда вещей. Например, 2010 год более правдоподобен, чем год 10.

  • посмотрите в каждую из трех корзин. Если в каком-либо из них есть только один элемент, это значение для этого сегмента. Он также удален из других ведер.

  • ищут оставшиеся пропущенные значения в соответствующих сегментах по порядку (год, месяц, день), выбирая наиболее правдоподобное. В случае ничьей возьмите тот, который встречается последним в строке (на самом деле, у них немного больше правдоподобия).Эти правила нарушают 7/3/2010 как 7 марта, как мне нужно здесь, во Франции. Удалите это значение из других сегментов, если это применимо.

  • если какое-либо значение отсутствует, используйте значение по умолчанию (например, я использую 8191 как год по умолчанию, самое большое допустимое значение в моей целевой системе).

Все это ужасно эвристика, но соответствует моему требованию, что лучше иметь мусор, чем терять информацию.

2
ответ дан 13 December 2019 в 19:33
поделиться

Date :: Manip - ваш друг, так как он терпит неудачу только в одном из четырех, потому что он принимает формат США, используя Date_Init, вы можете получить 4 из 4.

Если у вас есть разные форматы (например, месяц до дня и наоборот), вам придется анализировать их по-разному, один раз с форматом даты в США, а следующий с форматом даты, отличным от американского. Это особенно важно, когда он неоднозначен, как ваш пример 3/4/97, потому что, если он 21/3, он просто не работает, и вы можете сказать, что формат неправильный.

vinko@mithril:~$ more date.pl
use strict;
use warnings;
use Date::Manip;

my @a;
push @a, "March 2004";
push @a, "2001";
push @a, "3/4/97";
push @a, "21/3/1998";
Date_Init("DateFormat=non-US");
for my $d (@a) {
    print "$d\n";
    print ParseDate($d)."\n";
};
vinko@mithril:~$ perl date.pl
March 2004
2004030100:00:00
2001
2001010100:00:00
3/4/97
1997040300:00:00
21/3/1998
1998032100:00:00
4
ответ дан 13 December 2019 в 19:33
поделиться
4
ответ дан 13 December 2019 в 19:33
поделиться

Вы также можете взглянуть на DateTime :: Format :: Flexible

Судя по его описанию, он вам подойдет:

Если вам когда-либо приходилось использовать программу что заставило вас ввести дату определенным образом и подумал: "Почему не может компьютер просто выяснил, какого числа я хотел? ", этот модуль для вас.

DateTime :: Format :: Гибкие попытки возьмите любую строку, которую вы ей даете, и проанализируйте в объект DateTime.

Я только что запустил версию сценария Vinko, используя этот модуль, и получил аналогичные результаты. Все нормально, кроме последнего случая (21.03.1998). Как и в случае с Date :: Manip , вы можете относительно легко справиться с этим, явно задав параметр ( european => 1 ). Комментарий Данбистрома показывает, почему такие дела нуждаются в надзоре со стороны человека.

1
ответ дан 13 December 2019 в 19:33
поделиться

Это не Perl, но эта библиотека .NET будет анализировать широкий диапазон строк даты и времени.

0
ответ дан 13 December 2019 в 19:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: