2011-12-21 2 views
2

В моем приложении MVC3 на одном из объектов я сохраняю Дата рождения в виде строки. Зачем ? потому что мое приложение позволяет хранить дату рождения людей, давно умерших, например. Сократ, Платон, Эпикур ... и т. Д., И насколько я знаю, класс DateTime этого не позволяет.RegEx String Validator

Теперь, очевидно, что мы точно не знаем точную дату рождения Epicurus, мы просто знаем год рождения [341 BCE], поэтому то, что я собираюсь сделать, - это создание специального валидатора, который будет проверять строка ввода для даты рождения и убедитесь, что все они соответствуют следующему формату:

12 Feb 1809 
Feb 1809 
341 
341 BCE 
Oct 341 BCE 
11 Mar 5 BCE 

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

Я пытался в течение нескольких часов, а не получить в любом месте: s

ОБНОВЛЕНИЕ В ОТВЕТ НА ПРЕДОСТАВЛЯЕМЫХ ОТВЕТЫ: ​​

Большое спасибо, ребята, если бы я был так же хорошо, как вы много в здании RegExes! Поскольку мое приложение связано с ASP.net MVC3, я хотел бы придерживаться класса .NET RegEx (для удобства).

luastoned ответ похоже работа !! Кажется, я не могу сломать его логику со всеми тестовыми данными, которые я выбрал.

Одна вещь, хотя, могу ли я также разрешить BC? потому что некоторые люди используют BC, а другие используют BCE <, что было бы возможно? И ... Правильно ли, что регулярное выражение не может заменить BC на BCE? Я должен сделать это вручную с помощью кода на C# правильно? RegEx будет просто соответствовать или нет .. правильно?

UPDATE TWO:

Regular Expression M42, кажется, работает лучше. Я только что скопировал его и использовал его в своем пользовательском валидаторе (код в ссылке PasteBin ниже).

Thank you.

ответ

1

Как насчет:

/^(?:\d+\s)?(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)?(?:\s?\d+)(?:\sBCE)?$/ 

Вот Perl скрипт с тестов:

#!/usr/local/bin/perl 
use strict; 
use warnings; 
use Test::More; 

my $re1 = qr/^(?:\d+\s)?(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)?(?:\s?\d+)(?:\sBCE)?$/; 
while(<DATA>) { 
    chomp; 
    if (/$re1/) { 
     ok(1, "input = $_"); 
    } else { 
     ok(0, "input = $_"); 
    } 
} 
done_testing; 

__DATA__ 
12 Feb 1809 
Feb 1809 
341 
341 BCE 
Oct 341 BCE 
11 Mar 5 BCE 
12D09 
1s909 
A3 43 4 BCE 
a 1 
3F9 

abc 
BCE 
123b456 

выход:

# Looks like you failed 9 tests of 15. 
ok 1 - input = 12 Feb 1809 
ok 2 - input = Feb 1809 
ok 3 - input = 341 
ok 4 - input = 341 BCE 
ok 5 - input = Oct 341 BCE 
ok 6 - input = 11 Mar 5 BCE 
not ok 7 - input = 12D09 
not ok 8 - input = 1s909 
not ok 9 - input = A3 43 4 BCE 
not ok 10 - input = a 1 
not ok 11 - input = 3F9 
not ok 12 - input = 
not ok 13 - input = abc 
not ok 14 - input = BCE 
not ok 15 - input = 123b456 
1

это выглядит любит Вейрдест Regex я когда-либо сделал:

(\d+\s?)?(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)?\s(\d+\s)?(BCE)?

Я понятия не имею, сколько ложных срабатываний будет пройти хотя ..

Вы можете проверить образец на Regexr

+0

Почему '(BCE | \ d {4})? '? '(BCE)?' Должно быть достаточным, так как 'BCE' является последним (годы в примерах OP являются' 1809', '1809',' 341', '341',' 341' и '5' соответственно с последними тремя будучи BCE.) – jensgram

+0

Вы правы - исправлено это, спасибо. – luastoned

+1

Это соответствует: '" "' - строка, содержащая одно пространство. Выражение также должно содержать якобы '^' и '$'. – ridgerunner

0

Не совсем знакомый RegExr (и не зная ограничений регулярных выражений в MVC3), позвольте мне представить версию PHP с именованными захватами (demo):

(?:(?:(?P<date>\d{1,2})\s)?(?P<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))?(?:(?:^|\s)(?P<year>\d+))?(?:\s(?P<bce>BCE))? 

Основано на @ luastoned's answer.