Проверка номера кредитной карты Regex

Я тестирую одно приложение, в котором шаблон Regex соответствует кредитной карте, тогда такие числа должны быть выделены. Я использую сайт http://regexpal.com/ для создания номеров тестовых кредитных карт для моего тестирования. Мое требование - иметь действующие номера кредитных карт, между которыми может стоять "-" и / или ",". Мне не удалось создать такой номер, когда я тестировал его на сайте

http://regexpal.com.

Мне нужно несколько номеров кредитов со сценариями ниже

  1. действующий номер кредитной карты, в котором между любыми цифрами может стоять знак «-».
  2. действительный номер кредитной карты, который может содержать "," между любыми цифрами.
  3. действующий номер кредитной карты, который может содержать комбинацию символов «,» или «-» между любой цифрой.

person user1209784    schedule 16.02.2012    source источник
comment
На каком языке вы это пишете? В зависимости от языка может быть проще выполнить удаление с помощью поиска и замены для - и , перед проверкой с помощью регулярного выражения.   -  person    schedule 16.02.2012
comment
Это связано с java-скриптом, поскольку на сайте используется RegexPal 0.1.4 - тестер регулярных выражений JavaScript.   -  person user1209784    schedule 16.02.2012
comment
вы можете обратиться к этому руководству по регулярным выражениям - youtube.com/watch?v=M1iFcFUn3qw   -  person Krishnraj Rana    schedule 05.07.2020


Ответы (13)


Сначала удалите из строки все , и - и другие нецифровые цифры.

Затем используйте это регулярное выражение, которое соответствует картам Visa, MasterCard, American Express, Diners Club, Discover и JCB:

^(?:4[0-9]{12}(?:[0-9]{3})?|[25][1-7][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$

person Alexander Pavlov    schedule 16.02.2012
comment
Вы можете изменить свой ответ, включив в него действительное регулярное выражение для кредитных карт, которое вы можете найти здесь: regular-expressions.info/creditcard.html - person ; 16.02.2012
comment
что, если номер кредитной карты не непрерывный, например 4111111111111111, и я помещаю его в способ 4111 1111 1111 1111? это дает ошибку. - person saadk; 13.11.2014
comment
@saadk удаляет нечисловые символы из ввода перед проверкой. - person Onur Yıldırım; 24.12.2014
comment
@saadk Нечисловые значения всегда игнорируются. - person Shubham A.; 05.06.2015
comment
Это необходимо будет обновить в ближайшее время, чтобы обработать добавление 2 BIN мастер-карт. mastercard.us/en-us/issuers/get-support/ - person Joshua Belden; 22.09.2016
comment
MasterCard добавит номер 222100-272099 14 октября 2016 года. Так что, если я правильно прочитаю, это больше не будет ловить все их карты. - person Slagmoth; 26.09.2016
comment
Я считаю, что вам нужно использовать [25][1-7][0-9]{14} для новых номеров MC - person skwidbreth; 29.03.2017

Распространенные регулярные выражения для поставщиков кредитных карт:

  • Карта Amex: ^3[47][0-9]{13}$
  • BCGlobal: ^(6541|6556)[0-9]{12}$
  • Карта карт-бланш: ^389[0-9]{11}$
  • Карта Diners Club: ^3(?:0[0-5]|[68][0-9])[0-9]{11}$
  • Откройте для себя карту: ^65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}|(622(?:12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])[0-9]{10})$
  • Платежная карта Insta: ^63[7-9][0-9]{13}$
  • Карта JCB: ^(?:2131|1800|35\d{3})\d{11}$
  • KoreanLocalCard: ^9[0-9]{15}$
  • Лазерная карта: ^(6304|6706|6709|6771)[0-9]{12,15}$
  • Карточка маэстро: ^(5018|5020|5038|6304|6759|6761|6763)[0-9]{8,15}$
  • Mastercard: ^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$
  • Индивидуальная карта: ^(6334|6767)[0-9]{12}|(6334|6767)[0-9]{14}|(6334|6767)[0-9]{15}$
  • Карточка переключения: ^(4903|4905|4911|4936|6333|6759)[0-9]{12}|(4903|4905|4911|4936|6333|6759)[0-9]{14}|(4903|4905|4911|4936|6333|6759)[0-9]{15}|564182[0-9]{10}|564182[0-9]{12}|564182[0-9]{13}|633110[0-9]{10}|633110[0-9]{12}|633110[0-9]{13}$
  • Карта Union Pay: ^(62[0-9]{14,17})$
  • Карта Visa: ^4[0-9]{12}(?:[0-9]{3})?$
  • Visa Master Card: ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})$
person ajithparamban    schedule 22.04.2014
comment
Отформатировав ваш ответ в виде списка, я бы отсортировал этот список по алфавиту, но я позволю вам решать. - person Mr. Polywhirl; 03.04.2015
comment
как разрешить пробелы и дефисы в этом регулярном выражении? - person Nikhil; 15.08.2016
comment
Стоит отметить, что с 2014-10-14 регулярного выражения MasterCard здесь будет недостаточно, поскольку они будут добавлять новый диапазон 222100-272099. Я только что добавил следующее для нашей проверки: ^ (?: 5 [1-5] [0-9] \ d {1} | 222 [1-9] | 2 [3-6] [0-9] \ d {1} | 27 [01] [0-9] | 2720) ([\ \ -]?) \ D {4} \ 1 \ d {4} \ 1 \ d {4} $ - person Slagmoth; 26.09.2016
comment
Обратите внимание, что Visa Master Card соответствует Visa или MasterCard и сама по себе не является типом карты. - person christinealittlebit; 15.11.2016
comment
Просто дружеское предупреждение: вы попадете в мир боли, если попытаетесь таким образом сопоставить определенные схемы и длину карт. Например, Switch не существует с 2002 года, Laser был отозван в 2014 году, Visa должна выпустить 19-значные карты, а MasterCard теперь выпускает карты с диапазоном 2xxxxx, просто чтобы выделить пару проблем с этим подходом. Регулярное выражение хорошо для базового, выглядит ли оно как номер карты, но не более того. - person PeteWiFi; 30.01.2017
comment
У кого-нибудь есть регулярное выражение для Apple Card? - person Mark; 18.09.2020
comment
Можно ли использовать регулярное выражение для карт EnRoute? - person Mohmmad S; 29.06.2021

2019

ДЕЛАТЬ. НЕТ. ИСПОЛЬЗОВАТЬ. REGEX !!! (с 3 восклицательными знаками)


Из комментариев я должен выделить комментарий PeteWiFi:

Просто дружеское предупреждение: вы попадете в мир боли, если попытаетесь таким образом сопоставить определенные схемы и длину карт. Например, Switch не существует с 2002 года, Laser был отозван в 2014 году, Visa должна выпустить 19-значные карты, а MasterCard теперь выпускает карты с диапазоном 2xxxxx, просто чтобы выделить пару проблем с этим подходом. Регулярное выражение хорошо для базового, выглядит ли оно как номер карты, но не более того.

Если вы хотите использовать регулярное выражение только для того, чтобы узнать бренд карты для визуального использования (например, для отображения логотипа или этикетки Visa), это нормально. Но если ваша логика кода зависит от этого, не используйте регулярное выражение и не используйте сторонние плагины / библиотеки!

Regex обнаруживает номера карт быстро и легко (я знаю, это так привлекательно!). Но в конечном итоге ваш проект столкнется с множеством серьезных и трудно решаемых ошибок. Эмитенты карт продолжают вводить новые шаблоны номеров карт или отзывать старые или могут полностью закрыться. Кто знает.


Решение

Создайте свое собственное решение (желательно без регулярного выражения) на основе некоторых официальных страниц, которые часто обновляются, например эта страница в Википедии..

Что касается -,., Пробела и всего прочего шума, просто удалите все эти нецифровые цифры, вы можете использовать это (на основе этого ответ):

$number = preg_replace("/[^0-9]/", "", "4111-1111 1111.1111");
// Output: 4111111111111111

Еще не уверены?

На этой странице подробно рассказывается, почему регулярное выражение - это ад. (Обратите внимание, в художественном произведении использовано слово «ад», потому что, оказавшись внутри, вы не можете выйти)

РЕДАКТИРОВАТЬ

Вот решение, которое я разработал (на PHP):

// Based on https://en.wikipedia.org/wiki/Payment_card_number
// This constant is used in get_card_brand()
// Note: We're not using regex anymore, with this approach way we can easily read/write/change bin series in this array for future changes
// Key     (string)           brand, keep it unique in the array
// Value   (array)            for each element in the array:
//   Key   (string)           prefix of card number, minimum 1 digit maximum 6 digits per prefix. You can use "dash" for range. Example: "34" card number starts with 34. Range Example: "34-36" (which means first 6 digits starts with 340000-369999) card number starts with 34, 35 or 36
//   Value (array of strings) valid length of card number. You can set multiple ones. You can also use "dash" for range. Example: "16" means length must be 16 digits. Range Example: "15-17" length must be 15, 16 or 17. Multiple values example: ["12", "15-17"] card number can be 12 or 15 or 16 or 17 digits
define('CARD_NUMBERS', [
    'american_express' => [
        '34' => ['15'],
        '37' => ['15'],
    ],
    'diners_club' => [
        '36'      => ['14-19'],
        '300-305' => ['16-19'],
        '3095'    => ['16-19'],
        '38-39'   => ['16-19'],
    ],
    'jcb' => [
        '3528-3589' => ['16-19'],
    ],
    'discover' => [
        '6011'          => ['16-19'],
        '622126-622925' => ['16-19'],
        '624000-626999' => ['16-19'],
        '628200-628899' => ['16-19'],
        '64'            => ['16-19'],
        '65'            => ['16-19'],
    ],
    'dankort' => [
        '5019' => ['16'],
        //'4571' => ['16'],// Co-branded with Visa, so it should appear as Visa
    ],
    'maestro' => [
        '6759'   => ['12-19'],
        '676770' => ['12-19'],
        '676774' => ['12-19'],
        '50'     => ['12-19'],
        '56-69'  => ['12-19'],
    ],
    'mastercard' => [
        '2221-2720' => ['16'],
        '51-55'     => ['16'],
    ],
    'unionpay' => [
        '81' => ['16'],// Treated as Discover cards on Discover network
    ],
    'visa' => [
        '4' => ['13-19'],// Including related/partner brands: Dankort, Electron, etc. Note: majority of Visa cards are 16 digits, few old Visa cards may have 13 digits, and Visa is introducing 19 digits cards
    ],
]);

/**
 * Pass card number and it will return brand if found
 * Examples:
 *     get_card_brand('4111111111111111');                    // Output: "visa"
 *     get_card_brand('4111.1111 1111-1111');                 // Output: "visa" function will remove following noises: dot, space and dash
 *     get_card_brand('411111######1111');                    // Output: "visa" function can handle hashed card numbers
 *     get_card_brand('41');                                  // Output: "" because invalid length
 *     get_card_brand('41', false);                           // Output: "visa" because we told function to not validate length
 *     get_card_brand('987', false);                          // Output: "" no match found
 *     get_card_brand('4111 1111 1111 1111 1111 1111');       // Output: "" no match found
 *     get_card_brand('4111 1111 1111 1111 1111 1111', false);// Output: "visa" because we told function to not validate length
 * Implementation Note: This function doesn't use regex, instead it compares digit by digit. 
 *                      Because we're not using regex in this function, it's easier to add/edit/delete new bin series to global constant CARD_NUMBERS
 * Performance Note: This function is extremely fast, less than 0.0001 seconds
 * @param  String|Int $cardNumber     (required) Card number to know its brand. Examples: 4111111111111111 or 4111 1111-1111.1111 or 411111###XXX1111
 * @param  Boolean    $validateLength (optional) If true then will check length of the card which must be correct. If false then will not check length of the card. For example you can pass 41 with $validateLength = false still this function will return "visa" correctly
 * @return String                                returns card brand if valid, otherwise returns empty string
 */
function get_card_brand($cardNumber, $validateLength = true) {
    $foundCardBrand = '';
    
    $cardNumber = (string)$cardNumber;
    $cardNumber = str_replace(['-', ' ', '.'], '', $cardNumber);// Trim and remove noise
    
    if(in_array(substr($cardNumber, 0, 1), ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])) {// Try to find card number only if first digit is a number, if not then there is no need to check
        $cardNumber = preg_replace('/[^0-9]/', '0', $cardNumber);// Set all non-digits to zero, like "X" and "#" that maybe used to hide some digits
        $cardNumber = str_pad($cardNumber, 6, '0', STR_PAD_RIGHT);// If $cardNumber passed is less than 6 digits, will append 0s on right to make it 6
        
        $firstSixDigits   = (int)substr($cardNumber, 0, 6);// Get first 6 digits
        $cardNumberLength = strlen($cardNumber);// Total digits of the card
        
        foreach(CARD_NUMBERS as $brand => $rows) {
            foreach($rows as $prefix => $lengths) {
                $prefix    = (string)$prefix;
                $prefixMin = 0;
                $prefixMax = 0;
                if(strpos($prefix, '-') !== false) {// If "dash" exist in prefix, then this is a range of prefixes
                    $prefixArray = explode('-', $prefix);
                    $prefixMin = (int)str_pad($prefixArray[0], 6, '0', STR_PAD_RIGHT);
                    $prefixMax = (int)str_pad($prefixArray[1], 6, '9', STR_PAD_RIGHT);
                } else {// This is fixed prefix
                    $prefixMin = (int)str_pad($prefix, 6, '0', STR_PAD_RIGHT);
                    $prefixMax = (int)str_pad($prefix, 6, '9', STR_PAD_RIGHT);
                }

                $isValidPrefix = $firstSixDigits >= $prefixMin && $firstSixDigits <= $prefixMax;// Is string starts with the prefix

                if($isValidPrefix && !$validateLength) {
                    $foundCardBrand = $brand;
                    break 2;// Break from both loops
                }
                if($isValidPrefix && $validateLength) {
                    foreach($lengths as $length) {
                        $isValidLength = false;
                        if(strpos($length, '-') !== false) {// If "dash" exist in length, then this is a range of lengths
                            $lengthArray = explode('-', $length);
                            $minLength = (int)$lengthArray[0];
                            $maxLength = (int)$lengthArray[1];
                            $isValidLength = $cardNumberLength >= $minLength && $cardNumberLength <= $maxLength;
                        } else {// This is fixed length
                            $isValidLength = $cardNumberLength == (int)$length;
                        }
                        if($isValidLength) {
                            $foundCardBrand = $brand;
                            break 3;// Break from all 3 loops
                        }
                    }
                }
            }
        }
    }
    
    return $foundCardBrand;
}
person evilReiko    schedule 06.03.2019
comment
Я согласен с тем, что проверка должна включать не только сопоставление с образцом, но также включать проверку контрольной цифры, как указано в Википедии. Читаемость и обслуживание регулярных выражений также проблематичны в долгосрочной перспективе. - person Gee Bee; 16.05.2019
comment
Я знаю, что это довольно старый ответ, но (по крайней мере, в js) вы должны использовать следующий шаблон регулярного выражения, чтобы также учитывать точку: /[\D.]/ - person DadiBit; 28.10.2019
comment
Это правильное решение. Использование RegEx и их обновление - кошмар. - person Ethan Allen; 20.03.2021

Принятый ответ хорош, но я считаю, что для размещения нового MasterCard BIN его необходимо обновить до:

^(?:4[0-9]{12}(?:[0-9]{3})?|[25][1-7][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$

(критическая часть - [25][1-7][0-9]{14}, поскольку первая цифра теперь может быть либо 2, либо 5, а вторая цифра может быть до 7)

Пожалуйста, поправьте меня, если я ошибаюсь!

person skwidbreth    schedule 29.03.2017

Для дебетовой карты Rupay: ^6[0-9]{15}$

person Aditya Rao    schedule 06.01.2016
comment
@ trimul-rao Не могли бы вы проверить это? Это не сработало с моей картой Rupay Card. - person kartikmaji; 22.11.2017

Regex для ведущих карточных сетей

Основная карта (2 ячейки, 5 ячеек обе): "(?: 5 [1-5] [0-9] {2} | 222 [1-9] | 22 [3- 9] [0-9] | 2 [3-6] [0-9] {2} | 27 [01] [0-9] | 2720) [0-9] {12} "

Visa: "^ 4 [0-9] {6,} $"

Diner's Club: "(^ 30 [0-5] [0-9] {11} $) | (^ (36 | 38) [0-9] {12} $)"

American Express: "^ [34 | 37] [0-9] {14} $"

JCB: "(^ 3 [0-9] {15} $) | (^ (2131 | 1800) [0-9] {11} $)"

Откройте для себя: "^ 6011 -? \ d {4} -? \ d {4} -? \ d {4} $"

person Ripudaman Singh    schedule 23.11.2017
comment
Здравствуйте, у меня есть вопрос по вашему регулярному выражению American Express: я знаю, что карта Amex состоит из 15 цифр и начинается с 34 или 37, ваше регулярное выражение соответствует строке, начинающейся с 34 или 37, ТО 14 цифр, не Разве это не 16? Я тестировал его на Rubular, и он работает, скажите, пожалуйста, если я ошибаюсь в своих рассуждениях? - person Gnagno; 23.05.2018
comment
@Gnagno [34|37] неверно, поскольку [] используется для классов символов в любом механизме регулярных выражений, это будет НЕ совпадать с 34 или 37, это будет соответствовать либо 3, либо 4, либо | или 7. Правильный синтаксис был бы (34|37), здесь | действительно является чередованием, а круглые скобки просто ограничивают начало и конец параметров. - person Patrick Mevzek; 29.08.2018

В дополнение ко всему вышесказанному, вот регулярное выражение для новых карт MasterCard, которое включает 2221–2720 BIN:

^5[1-5][0-9]{0,14}|^(222[1-9]|2[3-6]\\d{2}|27[0-1]\\d|2720)[0-9]{0,12}

Обратите внимание, это регулярное выражение будет соответствовать, если пользователь начнет вводить цифры карты, соответствующие MasterCard. Например, если пользователь вводит «222185», то регулярное выражение будет соответствовать, потому что нет другого типа карточки, которая начинается с «2221». Это регулярное выражение может пригодиться, если вы хотите отображать тип карты при вводе первых цифр карты.

В качестве альтернативы, если вы хотите сопоставить "постфактум", вы можете изменить последнюю часть с {0,14} и {0,12} на {14} и {12}:

^5[1-5][0-9]{14}|^(222[1-9]|2[3-6]\\d{2}|27[0-1]\\d|2720)[0-9]{12}
person azizbekian    schedule 18.04.2018
comment
5[1-5][0-9]{0,15} должно быть 5[1-5][0-9]{0,14}, а если вы хотите точное совпадение, оно должно быть {14} в нижнем шаблоне в дополнение к {12} в конце. - person jimp; 20.07.2018
comment
@azizbekian - Что делать, если номер карты 5555 5555 5555 4444, это сработает? - person Neel; 09.08.2018
comment
@ Нил, да, будет. 5[1-5][0-9]{14} эта часть регулярного выражения будет соответствовать вашему вводу. - person azizbekian; 09.08.2018
comment
Не совпадает, не могли бы вы попробовать? @azizbekian - regex101.com - person Neel; 09.08.2018
comment
@Neel, вы удалили все пробелы из строки перед сопоставлением? Выполните сопоставление с 5555555555554444, не с 5555 5555 5555 4444. - person azizbekian; 09.08.2018
comment
Хорошо, это был мой вопрос, будет ли это работать с 5555 5555 5555 4444? Мой вариант использования - совпадение с пробелом или без него @azizbekian - person Neel; 09.08.2018
comment
Ни одно из регулярных выражений, которые вы видите в предоставленных ответах, не будет соответствовать любому номеру карты с пробелом. - person azizbekian; 09.08.2018
comment
@Neel Пробелы в номерах карт предназначены для человеческих глаз. Практически все реализации, которые я когда-либо видел, удаляют все нецифровые символы перед сопоставлением или обработкой карты. - person jimp; 16.08.2018

Для тех, кто пытается сделать это с помощью Swift (iOS), я создал небольшой проект, который не использует RegEx, который выполняет проверку префикса CC, проверку проверки цифр (с использованием алгоритма Луна) и несколько других интересных вещи. Его очень просто изменить, добавив новые типы карт и диапазоны номеров, без необходимости знать сложное регулярное выражение. Это похоже на то, что делает @evilReiko в своем ответе.

100% бесплатно. Полностью открытый исходный код.

https://github.com/ethanwa/credit-card-scanner-and-validator

person Ethan Allen    schedule 20.03.2021

Regx для карты Rupay:

(508[5-9][0-9]{12})|(6069[8-9][0-9]{11})|(607[0-8][0-9]{12})|(6079[0-8][0-9]{11})|(608[0-5][0-9]{12})|(6521[5-9][0-9]{11})|(652[2-9][0-9]{12})|(6530[0-9]{12})|(6531[0-4][0-9]{11})

с использованием серии бункеров: 508500 - 508999, 606985 - 606999, 607000 - 607899, 607900 - 607984, 608001 - 608500, 652150 --- 652199, 652200 --- 652999, 653000 --- 653099, 653100 --- 653149,

person Padam Singh    schedule 10.02.2016

Я придумал регулярное выражение, которое позволяет использовать тире и пробелы. Проверьте это здесь: https://regex101.com/r/Rx2iWD/1

Чтобы разрешить использование запятых (что я считаю необычным), просто добавьте их в определение sep.

В PHP:

$ccPatt = '/
    (?(DEFINE)
        (?<sep> [ -]?)
    )
    (?<!\d)(?:
      \d{4} (?&sep) \d{4} (?&sep) \d{4} (?&sep) \d{4}               # 16 digits
    | \d{3} (?&sep) \d{3} (?&sep) \d{3} (?&sep) \d (?&sep) \d{3}    # 13 digits
    | \d{4} (?&sep) \d{6} (?&sep) \d{4}                             # 14 digits
    | \d{4} (?&sep) \d{6} (?&sep) \d{5}                             # 15 digit card
    )(?!\d)
/xu';
person mpen    schedule 10.11.2016

Вот мой метод обнаружения сети карт (обновлен в 2020 г.):

function getCardBrandId($pan)
    {
        $regs = [
            ELECTRON => "/^(4026|417500|4405|4508|4844|4913|4917)\d+$/",
            MAESTRO  => "/^(?:50|5[6-9]|6[0-9])\d+$/",
            DANKORT  => "/^(5019|4571)\d+$/",
            CUP      => "/^(62|81)\d+$/",
            VISA     => "/^4[0-9]\d+$/",
            DINERS   => "/^(?:5[45]|36|30[0-5]|3095|3[8-9])\d+$/",
            MC       => "/^(?:5[1-5]|222[1-9]|22[3-9][0-9]|2[3-6][0-9][0-9]|27[0-1][0-9]|2720)\d+$/",
            AMEX     => "/^(34|37)\d+$/",
            DISCOVER => "/^6(?:011|22(12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])|5|4|2[4-6][0-9]{3}|28[2-8][0-9]{2})\d+$/",
            JCB      => "/^(?:35[2-8][0-9])\d+$/",
            INTERPAY => "/^(636)\d+$/",
            KOREAN   => "/^9[0-9]\d+$/",
            MIR      => "/^(?:220[0-4])\d+$/",
        ];


        foreach ($regs as $brand => $reg) {
            if (preg_match($reg, $pan)) {
                return $brand;
            }
        }

        return "Unknown";
    }
person Arm092    schedule 02.06.2020
comment
В регулярном выражении MAESTRO отсутствуют разделители, а в шаблоне DISCOVER нет $, это предназначено? - person Wiktor Stribiżew; 02.07.2020
comment
не работает на 4000-0000-0000-0000 - person Assaf Livne; 11.03.2021
comment
Он должен вернуть VISA, просто удалите символы минус - person Arm092; 13.03.2021

First Data проверяет 15 цифр для Amex и 16 для visa, mc, discover, diners и jcb, поэтому я отправляю им только номер карты, если номер 15 или 16 цифр, используя это:

^[0-9]{15}(?:[0-9]{1})?$
person Bolo    schedule 14.09.2017

Регулярное выражение для всех типов карт

^(3[47][0-9]{13}|(6541|6556)[0-9]{12}|389[0-9]{11}|3(?:0[0-5]|[68][0-9])[0-9]{11}|65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}|(622(?:12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])[0-9]{10})|63[7-9][0-9]{13}|(?:2131|1800|35\d{3})\d{11}|9[0-9]{15}|(6304|6706|6709|6771)[0-9]{12,15}|(5018|5020|5038|6304|6759|6761|6763)[0-9]{8,15}|(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))|(6334|6767)[0-9]{12}|(6334|6767)[0-9]{14}|(6334|6767)[0-9]{15}|(4903|4905|4911|4936|6333|6759)[0-9]{12}|(4903|4905|4911|4936|6333|6759)[0-9]{14}|(4903|4905|4911|4936|6333|6759)[0-9]{15}|564182[0-9]{10}|564182[0-9]{12}|564182[0-9]{13}|633110[0-9]{10}|633110[0-9]{12}|633110[0-9]{13}|(62[0-9]{14,17})|4[0-9]{12}(?:[0-9]{3})?|(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}))$

Проверить можно здесь https://regex101.com/r/37S1iV/1

person sVIKs    schedule 29.04.2021