Regular Expression date validation error - regex

I'm very new in regular expression and I'm trying to validate date using following regular expression here:
^[1-31]\.[1-12]\.[1999-2005]$
but I'm getting an output as "invalid reguar expression"
Could anyone please tell me what's wrong I'm doing in above regular expression?

Regular expressions can't match ranges of numbers, like you're doing with [1-31]. It can only match ranges of characters. You would need to match [1-31] as ([12]?[0-9]|3[01]) instead—it's not the most friendly thing in the world.

You can use:
[0-9]{2}.[0-9]{2}.[0-9]{4}
or
^(0[1-9]|[12][0-9]|3[01]).(0[1-9]|1[012]).(19|20)[0-9]{2}$
both will match your date but wont validate it.
I doubt that regular expression is a good way to validate a date due to the fact that you must check between 30 and 31 and also 28 plus leap years.
Probably there is a regular expression which handle all combination including leap years. But I recommend to use the existing function of your environment.
For example with PHP use checkdate() or the date class if you use Ruby.

try this:
^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)[0-9]{2}$
it can match following strings~
12.12.1999
12-12-1999
12 12 1999
12/12/1999

I do that, it worked perfectly ...
for(var i=0; i<100;i++){
if( /^([1-9]|[1-2][0-9]|[3][0-1])$/.test(i) ) {
console.log(i);
}
}
// display only the range of 1 to 31 and disregards the 32-100

Related

regular expression for a match to a specific date

I have a need to find a match for any kind of legit date format, but - for a specific given date only, that I am given as a parameter.
for example: 01-05-2020
I need it to match as many formats as possible, such as, but not only : 01/05/2020, 1/5/20, 05-01-2020 2020-05-01, and so on.
not match: 02-05-2020, or any other date that is not the first of May 2020.
thanks,
Dani
As upog already said, you must have a constant format for the month and date. 5th jan and 1st may can easily switch places. However given you have a constant format we can construct a regex.
For the format - Date/Month/Year and Date-Month-Year. You can construct a regex to match 1st may of 2020 like so-
^0?1[\/\-]0?5[\/\-](?:20)?20$
Live demo
For the format - Month/Date/Year and Month-Date-Year. You can construct a regex to match 1st may of 2020 like so-
^0?5[\/\-]0?1[\/\-](?:20)?20$
Live demo

Gawk regular expression for days in month

Im writing regular expression that accepts days in months ([0-3])([0-9]). How to change it so it will only accept proper amount of days from 1 to 31, but not 37 like mine... i tried alternation |, but i don't know how to include first group into it.
([0-2])([0-9])|(3)([0-1]) does not work
How to change it so i will have still 2 groups and proper dates?
edit: 2 groups, not 4
Try this :
(0)([1-9])|(1|2)([0-9])|(3)(0|1)
DEMO Match numbers between 01 and 31 only
(0[1-9]|[12][0-9]|3[01])
This accepts values between 0-31 in one group, but does not care about about that February has no days as 30,31.
Sorry, misread it.
If you want to get the values in two groups you have to use negative lookahead like so:
([0-2]|3(?![^0-1]))([0-9])
But I think gawk does not support this.

What's wrong with this (mm-dd-yyyy) regular expression?

I'm trying to validate mm-dd-(2012~2099) date format.
I have the following regular expression.
^(0[1-9]|1[0-2])-(0[1-9]|[10-31])-(20[12-99])$
when I run the following code, I get false. What's wrong with this regular expression?
var reg = new RegExp("^(0[1-9]|1[0-2])-(0[1-9]|[10-31])-(20[12-99])$")
reg.test("05-33-2012")**
When I take out the year part, and then test "05-33", it works.
As Oli said, [12-99] does not do what you think it does.
Specifically, the - refers to a range of characters, not numbers. So [12-99] matches...
1
2-9
9
The expression 20(1[2-9]|[2-9][0-9]) would work for dates 2012-2099

Regular Expression Match to test for a valid year

Given a value I want to validate it to check if it is a valid year. My criteria is simple where the value should be an integer with 4 characters. I know this is not the best solution as it will not allow years before 1000 and will allow years such as 5000. This criteria is adequate for my current scenario.
What I came up with is
\d{4}$
While this works it also allows negative values.
How do I ensure that only positive integers are allowed?
Years from 1000 to 2999
^[12][0-9]{3}$
For 1900-2099
^(19|20)\d{2}$
You need to add a start anchor ^ as:
^\d{4}$
Your regex \d{4}$ will match strings that end with 4 digits. So input like -1234 will be accepted.
By adding the start anchor you match only those strings that begin and end with 4 digits, which effectively means they must contain only 4 digits.
The "accepted" answer to this question is both incorrect and myopic.
It is incorrect in that it will match strings like 0001, which is not a valid year.
It is myopic in that it will not match any values above 9999. Have we already forgotten the lessons of Y2K? Instead, use the regular expression:
^[1-9]\d{3,}$
If you need to match years in the past, in addition to years in the future, you could use this regular expression to match any positive integer:
^[1-9]\d*$
Even if you don't expect dates from the past, you may want to use this regular expression anyway, just in case someone invents a time machine and wants to take your software back with them.
Note: This regular expression will match all years, including those before the year 1, since they are typically represented with a BC designation instead of a negative integer. Of course, this convention could change over the next few millennia, so your best option is to match any integer—positive or negative—with the following regular expression:
^-?[1-9]\d*$
This works for 1900 to 2099:
/(?:(?:19|20)[0-9]{2})/
Building on #r92 answer, for years 1970-2019:
(19[789]\d|20[01]\d)
To test a year in a string which contains other words along with the year you can use the following regex: \b\d{4}\b
In theory the 4 digit option is right. But in practice it might be better to have 1900-2099 range.
Additionally it need to be non-capturing group. Many comments and answers propose capturing grouping which is not proper IMHO. Because for matching it might work, but for extracting matches using regex it will extract 4 digit numbers and two digit (19 and 20) numbers also because of paranthesis.
This will work for exact matching using non-capturing groups:
(?:19|20)\d{2}
Use;
^(19|[2-9][0-9])\d{2}$
for years 1900 - 9999.
No need to worry for 9999 and onwards - A.I. will be doing all programming by then !!! Hehehehe
You can test your regex at https://regex101.com/
Also more info about non-capturing groups ( mentioned in one the comments above ) here http://www.manifold.net/doc/radian/why_do_non-capture_groups_exist_.htm
you can go with sth like [^-]\d{4}$: you prevent the minus sign - to be before your 4 digits.
you can also use ^\d{4}$ with ^ to catch the beginning of the string. It depends on your scenario actually...
/^\d{4}$/
This will check if a string consists of only 4 numbers. In this scenario, to input a year 989, you can give 0989 instead.
You could convert your integer into a string. As the minus sign will not match the digits, you will have no negative years.
I use this regex in Java ^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19|[2-9][0-9])[0-9]{2}$
Works from 1900 to 9999
If you need to match YYYY or YYYYMMDD you can use:
^((?:(?:(?:(?:(?:[1-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:[2468][048]|[13579][26])00))(?:0?2(?:29)))|(?:(?:[1-9]\d{3})(?:(?:(?:0?[13578]|1[02])(?:31))|(?:(?:0?[13-9]|1[0-2])(?:29|30))|(?:(?:0?[1-9])|(?:1[0-2]))(?:0?[1-9]|1\d|2[0-8])))))|(?:19|20)\d{2})$
You can also use this one.
([0-2][0-9]|3[0-1])\/([0-1][0-2])\/(19[789]\d|20[01]\d)
In my case I wanted to match a string which ends with a year (4 digits) like this for example:
Oct 2020
Nov 2020
Dec 2020
Jan 2021
It'll return true with this one:
var sheetName = 'Jan 2021';
var yearRegex = new RegExp("\b\d{4}$");
var isMonthSheet = yearRegex.test(sheetName);
Logger.log('isMonthSheet = ' + isMonthSheet);
The code above is used in Apps Script.
Here's the link to test the Regex above: https://regex101.com/r/SzYQLN/1
You can try the following to capture valid year from a string:
.*(19\d{2}|20\d{2}).*
Works from 1950 to 2099 and value is an integer with 4 characters
^(?=.*?(19[56789]|20\d{2}).*)\d{4}$

Regular Expression to match dates in dd/mm/yy format and check for valid values

Does anyone have a regurlar expression available which only accepts dates in the format dd/mm/yy but also has strict checking to make sure that the date is valid, including leap year support?
I am coding in vb.net and am struggling to work this one out.
I don't think the leap year support is doable in a regex without using some ugly regex.
You will have to check the date validity after validating input with the regex.
As hinted by Keeper, you could use the DateTime.ParseExact method to validate your date :
Public Function IsValidDate(ByVal dateString As String) As Boolean
Try
DateTime.ParseExact(dateString, "dd/MM/yy", System.Globalization.CultureInfo.InvariantCulture)
Return True
Catch ex As FormatException
Return False
End Try
End Function
Apart from the fact that such a regex would be a long dirty unmaintainable thing if it existed, you can't even tell for sure if an year in YY format is a leap year or not. 00 is leap if and only if it is a multiple of 400. 2000 was leap, 1900 wasn't.
The following regex makes sure that date is between 01 and 31, month is between 01 and 12 and year is between 1900 and 2099. Delete the (?:19|20) part to make it dd/mm/yy format: then year can be anything from 00 to 99. Do the real validation using standard date-time libraries - use the regex for just client side validations (to save a trip to server - assuming you're doing date-time validation at server), or as a screening test before feeding to the real validator.
^(0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/((?:19|20)\d{2})$
It will be hard, or ugly and a maintenance nightmare, or even impossible.
Just do a check in code after Regex validation.
No need to use a regex because there's already a date parsing function: DateTime.ParseExact
I think it is extreamly hard to check whether year leap or not with reqular expression. Please take a look at this article about your problem. Here is a citate from here:
Again, how complex you want to make
your regular expression depends on the
data you are using it on, and how big
a problem it is if an unwanted match
slips through. If you are validating
the user's input of a date in a
script, it is probably easier to do
certain checks outside of the regex.
For example, excluding February 29th
when the year is not a leap year is
far easier to do in a scripting
language. It is far easier to check if
a year is divisible by 4 (and not
divisible by 100 unless divisible by
400) using simple arithmetic than
using regular expressions.
You'd probably be better off just doing the format-validation in regex and handling the date-validation separately.
You're trying to use the regex hammer to solve an eminently non-nail shaped problem.
Would it not be better to extract the numbers using regular expressions, but validate it programatically?
There is no need to verify the format because the "parse" methods will do this for you. the parse will compare all date format strings in DateTimeFormatInfo against the string you pass to the method. The parse-exact method will only compare the specified string against the data format strings you pass to the method.
Imports System.Globalization
Module Sample
Public Function IsValidDateString1(ByVal s As String) As Boolean
Return Date.TryParseExact(s, "dd/MM/yy", CultureInfo.InvariantCulture, DateTimeStyles.None, Nothing)
End Function
Public Function IsValidDateString2(ByVal s As String) As Boolean
Static _dateFormats() As String = New String() {"dd/MM/yy", "d/M/yy", "d/M/yyyy"}
Return Date.TryParseExact(s, _dateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, Nothing)
End Function
Public Sub Main()
Debug.WriteLine("single")
Debug.WriteLine(IsValidDateString1("31/12/2001")) 'wrong format
Debug.WriteLine(IsValidDateString1("31/12/01"))
Debug.WriteLine(IsValidDateString1("29/2/08")) '<-be careful
Debug.WriteLine(IsValidDateString1("29/ 2/08")) '<-be careful
Debug.WriteLine(IsValidDateString1("29/02/08"))
Debug.WriteLine(IsValidDateString1("29/02/09")) 'invalide date
Debug.WriteLine("multiple")
Debug.WriteLine(IsValidDateString2("31/12/2001"))
Debug.WriteLine(IsValidDateString2("31/12/01"))
Debug.WriteLine(IsValidDateString2("29/2/08"))
Debug.WriteLine(IsValidDateString2("29/ 2/08")) '<-be careful
Debug.WriteLine(IsValidDateString2("29/02/08"))
Debug.WriteLine(IsValidDateString2("29/02/09")) 'invalid date
End Sub
End Module