import re
regex = re.compile(r"\b(?<!\d.)(3[47]\d{2}([ -]?)(?!(\d)\3{5}|123456|234567|345678|424242|545454)\d{6}\2(?!(\d)\4{4})\d{5}|((4\d|5[1-5]|65)\d{2}|6011)([ -]?)(?!(\d)\8{3}|4242|5454|1234|3456|5678|2345|4567)\d{4}\7(?!(\d)\9{3})\d{4}\7\d{4})(\b|\s)(?!.\d\d)")
test_str = ("ALL strings in the first section should match\n"
"some 4270446050075048\n"
"4270-4460-5007-5048\n"
"this:4270 4460 5007 5048.\n"
"4270 4460 5007 5048 4/20\n"
"4270 4460 5007 5048 what\n"
"4270 4460 5007 5048\n"
"4270 4460 5007 5048 12/20 \n"
"5105105105105100\n"
"5200828282828210\n\n"
"--- (the following should not match - test numbers)\n"
"5454545454545454\n"
"4123456789012345\n"
"4242424242424242\n"
"42704460500750a8\n"
"4111111111111111\n"
"5111111111111111\n"
"5555555555555555\n"
"3333333333333333\n"
"3111111111111111\n\n"
"--- (the following should NOT match)\n"
"4270 4460 5007 5048 1234\n"
"4270\n"
"4270 4460 5007 504\n"
"42811293test123\n"
"427044605007504812345083 5095 5179 5157 5219 5187 5095 <--- FALSE POSITIVE (contains valid CC but has lots of exra digits)\n"
"this:4270 4460 5007 50482\n"
"4270 4460 5007 5048 123\n"
"4270 4460 5007 5048 1234\n\n"
"Known False positive (test number):\n"
"5535 3545 5455 4444\n")
matches = regex.finditer(test_str)
for match_num, match in enumerate(matches, start=1):
print(f"Match {match_num} was found at {match.start()}-{match.end()}: {match.group()}")
for group_num, group in enumerate(match.groups(), start=1):
print(f"Group {group_num} found at {match.start(group_num)}-{match.end(group_num)}: {group}")
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Python, please visit: https://docs.python.org/3/library/re.html