I suggest some minor improvements in the regular expression: - make sure that the same separator is used between day and month and between month and year with a backreference `(?P=sep)`, - replace numbered capture groups with named, and make non-needed groups, if there wer any, non-capturing with `?:`. Consequently, `finditer` and `groupdict` are used, and the day is obtained from the match with `int(date['day'])`, etc. This will make the code somewhat more human. More importantly, I suggest that you get rid of `days`, `months` and `years` lists altogether. These data can be stored in dictionaries in `dates` list and filtered prior to appending to `dates`. As a consequence, you won't need a loop over `range(len(days))`. The validation conditions can be OR'ed together without losing clarity, but I propose to make it a boolean variable to improve readability. Also, the only parametre in `date_detector` can be made typed: `def date_detector(text: str):`. To sum suggested modifications up: ```python import re def date_detector(text): date_pattern = re.compile(''' (?P<day>[12][0-9]|3[0-1]|0?[1-9]) # to detect days from 1 to 31 (?P<sep>[./-]) # to detect different separations (?P<month>1[0-2]|0?[1-9]) # to detect number of months (?P=sep) # to detect different seperations (?P<year>2?1?[0-9][0-9][0-9]) # to detect number of years from 1000-2999 years ''', re.VERBOSE) dates = [] for match in date_pattern.finditer(text): date = match.groupdict() # convert Match object to dictionary. del date['sep'] # we don't need the separator any more. date = {key: int(val) for key, val in date.items()} # apply int() to all items. date_is_valid = ( date['month'] not in (2, 4, 6, 9, 11) # 31 days in month (Jan, Mar, May, Jul, Aug, Oct, Dec). or date['day'] < 31 and date['month'] in (4, 6, 9, 11) # 30 days in month (Feb, Apr, Jun, Sep, Nov). or date['month'] == 2 and date['day'] == 29 and date['year'] % 4 == 0 and (date['year'] % 100 != 0 or date['year'] % 400 == 0) # February, 29th in a Gregorian leap year. or date['month'] == 2 and date['day'] < 29 # February, 1st-28th. ) if date_is_valid: dates.append(date) if len(dates) > 0: for date in dates: print(date) data = '30-06-2012, 31-12-2012, 15-02-2002, 29-02-2004, 29-02-2002, 31-02-2004, 31-06-2012' date_detector(data) ```