const regex = /(?(DEFINE)
(?<separator>\D?)
(?<iin> # issuer identification number for 16 and 19 digit cards
# MIR
220[0-4]
# Mastercard
| 222[1-9]
| 22[3-9]\d
| 2[3-6]\d{2}
| 27[01]\d
| 2720
| 5[1-5]\d{2}
# JCB
| 352[89]
| 35[3-8]\d
# Visa
| 4\d{3}
# Dankort
| 5019
# Discover
| 6011
| 622[1-9]
| 64[4-9]\d
| 65\d{2}
# InterPayment
| 63[7-9]\d
# UnionPay
| 62\d{2}
# Maestro
| 5[06-9]\d{2}
| 6\d{3}
# Troy
| 9792
)
)
## pattern begins here
\b
(?|
(?: # 14 digits: XXXX-XXXXXX-XXXX
# Diners Club
(?:
30[0-5]\d
| 36\d{2}
)
(?<sep>(?&separator))
\d{6}
\k<sep>
\d{4}
)
| (?: # 15 digits: XXXX-XXXXXX-XXXXX
# American Express
3[47]\d{2}
(?<sep>(?&separator))
\d{6}
\k<sep>
\d{5}
)
| (?: # 16 digits: XXXX-XXXX-XXXX-XXXX
(?&iin)
(?<sep>(?&separator))
\d{4}
\k<sep>
\d{4}
\k<sep>
\d{4}
)
| (?: # 19 digits: XXXXXXXXXXXXXXXXXXX
(?&iin)
\d{15}
)
)
\b/gm;
// Alternative syntax using RegExp constructor
// const regex = new RegExp('(?(DEFINE)
(?<separator>\\D?)
(?<iin> # issuer identification number for 16 and 19 digit cards
# MIR
220[0-4]
# Mastercard
| 222[1-9]
| 22[3-9]\\d
| 2[3-6]\\d{2}
| 27[01]\\d
| 2720
| 5[1-5]\\d{2}
# JCB
| 352[89]
| 35[3-8]\\d
# Visa
| 4\\d{3}
# Dankort
| 5019
# Discover
| 6011
| 622[1-9]
| 64[4-9]\\d
| 65\\d{2}
# InterPayment
| 63[7-9]\\d
# UnionPay
| 62\\d{2}
# Maestro
| 5[06-9]\\d{2}
| 6\\d{3}
# Troy
| 9792
)
)
## pattern begins here
\\b
(?|
(?: # 14 digits: XXXX-XXXXXX-XXXX
# Diners Club
(?:
30[0-5]\\d
| 36\\d{2}
)
(?<sep>(?&separator))
\\d{6}
\\k<sep>
\\d{4}
)
| (?: # 15 digits: XXXX-XXXXXX-XXXXX
# American Express
3[47]\\d{2}
(?<sep>(?&separator))
\\d{6}
\\k<sep>
\\d{5}
)
| (?: # 16 digits: XXXX-XXXX-XXXX-XXXX
(?&iin)
(?<sep>(?&separator))
\\d{4}
\\k<sep>
\\d{4}
\\k<sep>
\\d{4}
)
| (?: # 19 digits: XXXXXXXXXXXXXXXXXXX
(?&iin)
\\d{15}
)
)
\\b', 'gm')
const str = `VISA:
4916-0964-6896-0680,4716 4897 5598 3394 4024007191458214;4929677677283453911
MasterCard:
5324-3523-3637-8594 2221 0059 1411 2881 2720993802486259
American Express (AMEX):
3417-364760-63463
3703,747943,64738
345620254969461
Discover:
6011;1100;7456;3157
6011|3448|8657|7515
6011549504486287170
JCB:
3535#1626#1193#3330
3537w2194w6345w7160
3544115541621080497
Diners Club - North America:
5550@6773@7664@9628
5498!9120!2137!8785
5418926330224156
Diners Club - Carte Blanche:
3038~338630~9862
3043 979928 4843
30514730539784
Diners Club - International:
3601-529450-0216
3684 740236 6092
36068539661053
Maestro:
5038-1482-6826-8317
6761 1161 5463 2772
5020976162959049
Visa Electron:
4175-0064-3983-6063
4844 2214 1640 8361
4508772794670888
InstaPayment:
6375-9237-0580-9744
6387 4000 3155 2203
6387679822589033
UnionPay:
6257-8903-9875-9366
6283348562159853
6234512468972678451
Failed Luhn:
4024007191458216
4929677677283453917
Unrecognized IIN:
7135865572496322
3719865572496325
0139865572496321
7019865572496321
Improper spacing:
4024-0071 9145-8214
4024-00719145-8214
4024-007-19145-8214
3051-4730-5397-84
40240071914582144024007191458214
Unexpected length:
34562025496943
3498348562489555
305147305397847
3051473053978442
498348562489551
49834856248955837
498348562489558367
49834856248955836445`;
// Reset `lastIndex` if this regex is defined globally
// regex.lastIndex = 0;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
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 JavaScript, please visit: https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions