use strict;
my $str = '# Based on data from https://www.freeformatter.com/credit-card-number-generator-validator.html
# Currently only works for Visa, MasterCard, Discover, AmEx, JCB, Diners Club and only 16 digits (15 for AmEx, 14 for Diners Club Int\'l)
# VISA:
4600259666104540
4556-1328-5230-3974
4485733989514555546
# MasterCard:
5288718104904007
5183-2272-0427-5165
2221001473307772
# American Express (AMEX):
379094106835131
3767-607295-33484
345614253532917
# Discover:
6011277600566135
6011-7825-5703-7196
6011621290066569622
# JCB:
3542928645179210
3538837785961400
3540948375054149466
# Diners Club - North America:
5440569380986811
5500771351399605
5555244536769443
# Diners Club - Carte Blanche:
30360146296936
30381212693491
30178078889506
# Diners Club - International:
36760821695498
36861772048826
36442207191455
# Maestro:
6759789245430267
5893000324731008
5038101669768864
# Visa Electron:
4026108950062250
4913708902962931
4844361267840716
# InstaPayment:
6370603085892230
6390038329060763
6395957073920994';
my $regex = qr/(?# 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)/mxp;
if ( $str =~ /$regex/g ) {
print "Whole match is ${^MATCH} and its start/end positions can be obtained via \$-[0] and \$+[0]\n";
# print "Capture Group 1 is $1 and its start/end positions can be obtained via \$-[1] and \$+[1]\n";
# print "Capture Group 2 is $2 ... and so on\n";
}
# ${^POSTMATCH} and ${^PREMATCH} are also available with the use of '/p'
# Named capture groups can be called via $+{name}
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 Perl, please visit: http://perldoc.perl.org/perlre.html