I have some credit card numbers with me and want to validate them over the below rules.
► It must only consist of digits (0-9)
► It may have digits in groups of 4, separated by one hyphen “-“
► It must NOT have 4 or more consecutive repeated digits
► It may contain exactly digits without any spaces
Input:
5123-4567-8912-3456
61234-567-8912-3456
4123356789123456
5133-3367-8912-3456
Output:
Valid
Invalid (because the card number is not divided into equal groups of 4)
Valid
Invalid (consecutive 33 33digits is repeating 4 times)
I have tried here and it works only if i include hyphen at the end. Can somebody give me a correct reg ex for it.
Edit:
Regex Code: ([0-9]{4}-){4}
Input to be matched 6244-5567-8912-3458
It doesn’t match until I put hyphen at the end.
Edit
import re import itertools text="5133-3367-8912-3456" print(len(text)) l=[(k, sum(1 for i in g)) for k,g in itertools.groupby(text)] #To calculate frequency of characters and later we can filter it with the condition v<=3 for checking the concurrency condition if re.search(r'^[456]+',text) and len(text)==16 and re.search(r'[d]',text) and all(v<=3 for k,v in l) and bool(re.search(r's',text)) is False and bool(re.search(r'[a-z]',text)) is False or( bool(re.search(r'-',text))is True and len(text)==19) : print("it passed") else : print("False")
Advertisement
Answer
Your regex is almost correct. It asks for four dash terminated groups of numbers. What you want is three dash-terminated groups, followed by a non-dash-terminated group, or a single blob with no dashes:
(?:[0-9]{4}-){3}[0-9]{4}|[0-9]{16}
[Link]
I made the group non-capturing since you don’t need to capture the contents. You can also use d
instead of [0-9]
:
(?:d{4}-?){3}d{4}
[Link]
The validation of consecutive numbers is probably easier to do in a separate step. Once the regex match passes, remove all the dashes:
num = num.replace('-', '')
Now check for repeated digits using itertools.groupby, something like in this question/answer:
from itertools import groupby if max(len(list(g)) for _, g in groupby(num)) >= 4: print('Invalid: too many repeated digits')
Full Code
from itertools import groupby import re pattern = re.compile(r'(?:d{4}-){3}d{4}|d{16}') def count_consecutive(num): return max(len(list(g)) for _, g in groupby(num) num = '6244-5567-8912-3458' if not pattern.fullmatch(num) or count_consecutive(num.replace('-', '')) >= 4: print('Failed') else: print('Success')