import re
regex = re.compile(r"""
(?# This regex was created for the purposes of detecting potentially compromised credentials for the purposes of information security and not to be used for malicious purposes.)
(?<!\d)
(?# s - Short [less than 16 digits], m - Medium [16 digits], l - Long [more than 16 digits; not yet implemented])
(?# First four digits)
(?:
(?# Standard 16 digit numbers)
(?<m>
(?#MasterCard between 222100-272099)
222[1-9]|223\d|2[3-6]\d{2}|27[01]\d|2720|
(?#JCB is between 3528-3589)
352[89]|35[3-8]\d|
(?#Visa, MasterCard, Discover)
[4-6]\d{3}
)|
(?#American Express 15 digits | Diners Club 14 digits)
(?<s>(?<ax>3[47]\d{2})|(?<dc>30[0-5]\d|36\d{2}))
)
(?# Rest of the card number)
(?<del>\D+)?(?(<m>)\d{4}(?(<del>)\k{del})\d{4}(?(<del>)\k{del})\d{4}|(?:\d{6})(?(<del>)\k{del})(?(<ax>)\d{5}|\d{4}))
(?#END)
(?!\d)
""", flags=re.MULTILINE | re.VERBOSE)
test_str = ("# Based on data from https://www.freeformatter.com/credit-card-number-generator-validator.html\n\n"
"# Currently only works for Visa, MasterCard, Discover, AmEx, JCB, Diners Club and only 16 digits (15 for AmEx, 14 for Diners Club Int'l)\n\n"
"# VISA:\n"
"4600259666104540\n"
"4556-1328-5230-3974\n"
"4485733989514555546\n"
"# MasterCard:\n"
"5288718104904007\n"
"5183-2272-0427-5165\n"
"2221001473307772\n"
"# American Express (AMEX):\n"
"379094106835131\n"
"3767-607295-33484\n"
"345614253532917\n"
"# Discover:\n"
"6011277600566135\n"
"6011-7825-5703-7196\n"
"6011621290066569622\n"
"# JCB:\n"
"3542928645179210\n"
"3538837785961400\n"
"3540948375054149466\n"
"# Diners Club - North America:\n"
"5440569380986811\n"
"5500771351399605\n"
"5555244536769443\n"
"# Diners Club - Carte Blanche:\n"
"30360146296936\n"
"30381212693491\n"
"30178078889506\n"
"# Diners Club - International:\n"
"36760821695498\n"
"36861772048826\n"
"36442207191455\n"
"# Maestro:\n"
"6759789245430267\n"
"5893000324731008\n"
"5038101669768864\n"
"# Visa Electron:\n"
"4026108950062250\n"
"4913708902962931\n"
"4844361267840716\n"
"# InstaPayment:\n"
"6370603085892230\n"
"6390038329060763\n"
"6395957073920994")
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