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)
```