$re = '/(?(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/mx';
$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';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
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 PHP, please visit: http://php.net/manual/en/ref.pcre.php