3

I want to check if the format of the date input by user matches the below:

Jan 5 2018 6:10 PM

Month: First letter should be caps, followed 2 more in small. (total 3 letters)
<Space>: single space, must exist
Date: For single digit it should not be 05, but 5
<Space>: single space, must exist
Hour: 0-12, for single digit it should not be 06, but 6
Minute: 00-59
AM/PM

I'm using the below regex and trying to match:

import re,sys
usr_date = str(input("Please enter the older date until which you want to scan ? \n[Date Format Example: Jan 5 2018 6:10 PM] :  "))

valid_usr_date = re.search("^(\s+)*[A-Z]{1}[a-z]{2}\s{1}[1-31]{1}\s{1}[1-2]{1}[0-9]{1}[0-9]{1}[0-9]{1}\s{1}[0-12]{1}:[0-5]{1}[0-9]{1}\s{1}(A|P)M$",usr_date,re.M)

if not valid_usr_date:
    print ("The date format is incorrect. Please follow the exact date format as shown in example. Exiting Program!")
    sys.exit()

But, even for the correct format it gives a syntax wrong error. What am I doing wrong.

4
  • [1-31] matches 1, 2 or 3. Character classes do not work as you think they do. Commented Jan 30, 2018 at 8:18
  • 1
    @WiktorStribiżew you have the right answer, but you entered it as a "comment". Write it as an "answer" instead, and the questioner can give you credit for your answer! Commented Jan 30, 2018 at 8:19
  • Can I ask why use this format and not something that can be easily parsed by datetime.strptime? Commented Jan 30, 2018 at 8:31
  • @ReutSharabani This code above is part of a bigger code with a lot of functions defined. I already have certain functions where I'm parsing different parts of the date with datetime.strptime, but that is well ahead in my program. Before even going there I want to keep a validate function where I validate all inputs from user, and if doesn't validate, the program exits and doesn't go any further. Moreover I don't want to bind my program modules with multiple try: except:. I, rather am using sys.excepthook which captures all exceptions Commented Jan 30, 2018 at 9:09

2 Answers 2

8

I would not use regex for that, as you have no way to actually validate the date itself (eg, a regex will happily accept Abc 99 9876 9:99 PM).

Instead, use strptime:

from datetime import datetime

string = 'Jan 5 2018 6:10 PM'
datetime.strptime(string, '%b %d %Y %I:%M %p')

If the string would be in the "wrong" format you'd get a ValueError.

The only apparent "problem" with this approach is that for some reason you require the day and hour not to be zero-padded and strptime doesn't seem to have such directives.

A table with all available directives is here.

Sign up to request clarification or add additional context in comments.

Comments

1

You could use a function which parses the input string and tries to return a datetime object, if it can't it raises an ValueError:

from datetime import datetime

def valid_date(s):
    try:
        return datetime.strptime(s, '%Y-%m-%d %H:%M')
    except ValueError:
        msg = "Not a valid date: '{0}'.".format(s)
        raise argparse.ArgumentTypeError(msg)

1 Comment

This code I mentioned above in my query, is part of a bigger code with a lot of functions defined. I already have certain functions where I'm parsing different parts of the date with datetime.strptime, but that is well ahead in my program. Before even going there I want to keep a validate function where I validate all inputs from user, and if doesn't validate, the program exits and doesn't go any further. Moreover I don't want to bind my program modules with multiple try: except:. I, rather am using sys.excepthook which captures all exceptions

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.