J86
J86

Reputation: 15237

RegEx String Validator

In my MVC3 application, on one of the entities I am saving the Date of Birth as a string. Why ? because my application allows the storage of the date of birth of people long dead, eg. Socrates, Plato, Epicurus ... etc and as far as I know the DateTime class doesn't allow that.

Now obviously we don't know the exact date of birth of Epicurus for example, we just know the year of birth [ 341 BCE ], so what I am thinking of doing is building a custom validator, that will validate the input string for the Date of Birth and make sure that they all match the following format:

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

I need to write a regular expression that will match any of the above, and of course not match anything else.

Update

Thank you very much, I wish I was as good as you lot in building RegExes ! Since my application is with ASP.net MVC3, I would like to stick with the .NET RegEx class (for convenience's sake).

luastoned answer seems to work; I can't seem to break its logic with all the test data I've thrown at it.

One thing though, can I also allow BC? Because some people use BC and others use BCE < would that be possible? And, am I right that the regular expression can not replace BC with BCE? I have to do that manually through my C# code - the RegEx would just either match or not, is that correct?

Update 2

M42's Regular Expression seems to be working better. I've just copied it and used it in my Custom Validator (code in PasteBin link below).

Upvotes: 2

Views: 822

Answers (3)

Toto
Toto

Reputation: 91385

How about :

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

Here is a perl script with test cases:

#!/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

output:

# 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

Upvotes: 1

jensgram
jensgram

Reputation: 31508

Not quite a friend of RegExr (and not knowing the limitations of regexes in MVC3), allow me to present a PHP version with named captures (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))?

This is based on @luastoned's answer.

Upvotes: 0

luastoned
luastoned

Reputation: 663

this looks likes the weirdest Regex I've ever made:

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

I have no idea how many false positives would go through though..

You can check the sample on Regexr

Upvotes: 1

Related Questions