正则表达式信用卡号码测试

时间:2012-02-16 17:05:56

标签: regex regex-greedy

我正在测试一个Regex模式匹配信用卡的应用程序,然后突出显示这些数字。我正在使用网站http://regexpal.com/为我的测试创建测试信用卡信用卡号。我的要求是拥有有效的信用卡号码,它们之间可以有“ - ”和/或“,”。我没有成功建立这样的数字,就像我使用网站测试它一样

http://regexpal.com

我在下面的方案中需要很少的信用卡号

  1. 有效的信用卡号,任何数字之间可以有“ - ”。
  2. 有效的信用卡号码,任何数字之间可以有“,”。
  3. 有效的信用卡号码,可以在任何数字之间加上“,”或“ - ”。

14 个答案:

答案 0 :(得分:148)

普通信用卡供应商正则表达式:

  • 美国运通卡:^3[47][0-9]{13}$
  • BCGlobal:^(6541|6556)[0-9]{12}$
  • Carte Blanche卡片:^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})$
  • 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}$
  • Maestro Card:^(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})$
  • Visa卡:^4[0-9]{12}(?:[0-9]{3})?$
  • Visa Master Card:^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})$

答案 1 :(得分:50)

首先从字符串中删除所有,-以及其他非数字。

然后使用与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})$

答案 2 :(得分:6)

对于Rupay借记卡:^6[0-9]{15}$

答案 3 :(得分:6)

接受的答案很棒,但为了适应新的万事达卡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)

如果我错了,请纠正我!

答案 4 :(得分:1)

Regx for 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})

使用bin系列: 508500 - 508999, 606985 - 606999, 607000 - 607899, 607900 - 607984, 608001 - 608500, 652150 --- 652199, 652200 --- 652999, 653000 --- 653099, 653100 --- 653149,

答案 5 :(得分:1)

除上述所有内容外,这里还有新MasterCards的正则表达式,包括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}

注意,如果用户开始输入与万事达卡相对应的卡片数字,此正则表达式将匹配。例如,如果用户键入&#34; 222185&#34; ,那么正则表达式将匹配,因为没有其他类型的卡以&#34; 2221&#34; < / em>的。如果你想在输入卡片的第一个数字时显示卡片类型,这个正则表达式可能会派上用场。

或者,如果您想要&#34; post factum&#34; 匹配,您可以将最后一部分从{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}

答案 6 :(得分:1)

2019

DO。不。采用。 REGEX !!! (带有3个感叹号)


在评论中,我必须突出显示 PeteWiFi 的评论:

  

只是一个友好的警告,如果您尝试   以此方式匹配特定的方案和卡的长度。例如,开关   自2002年以来就不存在,Laser于2014年撤回,签证到期   发行19位数字卡,而万事达卡现在在2xxxxx中发行   范围,只是为了突出这种方法的几个问题。一种   regex适用于基本的“看起来像卡号”,但不是   远不止于此。

如果您想使用正则表达式只是为了了解视觉使用的卡片品牌(显示Visa徽标或标签),那很好。但是,如果您的代码逻辑依赖于此,则不要使用正则表达式,也不要使用第三方插件/库!

正则表达式检测卡号快速简便(我知道,这很吸引人!)。但是,从长远来看,您的项目将遇到许多严重且难以解决的错误。发卡机构不断推出新的卡号模式,或撤回旧的卡号模式,或可能完全关闭。谁知道。


解决方案

根据一些经常更新的官方页面(例如this page on wikipedia)构建您自己的解决方案(最好是非正则表达式)。

对于“-”,“。”,“空格”和所有其他噪声,只需删除所有这些非数字,就可以使用它(基于answer):

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

这里有一些technical details and many pitfalls

答案 7 :(得分:1)

对于尝试使用 Swift (iOS) 执行此操作的任何人,我构建了一个不使用 RegEx 的小项目,该项目执行 CC 前缀验证、校验位验证(使用 Luhn 算法)和其他一些很酷的东西。无需了解复杂的 RegEx 即可修改以添加新卡类型和号码范围非常简单。这类似于@evilReiko 在他的回答中所做的。

100% 免费。完全开源。

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

答案 8 :(得分:0)

我想出了一个允许破折号和空格的正则表达式。在此测试: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';

答案 9 :(得分:0)

First Data为Amex验证15位数,为签证,mc,发现,食客和jcb验证16位数,所以如果数字长度为15或16位,我只会将卡号发送给他们:

^[0-9]{15}(?:[0-9]{1})?$

答案 10 :(得分:0)

领先卡网络的正则表达式

万事达卡(2-Bin,5-Bin):&#34;(?: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}& #34;

签证:&#34; ^ 4 [0-9] {6,} $&#34;

晚餐俱乐部:&#34;(^ 30 [0-5] [0-9] {11} $)|(^(36 | 38)[0- 9] {12} $)&#34;

美国运通:&#34; ^ [34 | 37] [0-9] {14} $&#34;

JCB :&#34;(^ 3 [0-9] {15} $)|(^(2131 | 1800)[0-9] {11} $)&#34 ;

发现:&#34; ^ 6011 - ?\ d {4} - ?\ d {4} - ?\ d {4} $&#34;

答案 11 :(得分:0)

这是我的检测卡网络的方法(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";
    }

答案 12 :(得分:0)

适用于所有卡片类型的正则表达式

^(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

答案 13 :(得分:0)

我发现人们在 2021 年使用正则表达式来完成这项任务真的很烦人。 大多数信用卡号遵循 Luhn 算法,因此只需获取与银行等相关的字符,对于实际信用卡号,请使用此通用解决方案。 你不能简单地暴力解决这个问题。 我用现代风格重构了 python 3 中的 Luhn 算法。 最好使用这个相对较快的循环,性能也可能比正则表达式好。

    def check_luhn(cardNo: str) -> bool:
        res = 0
         
        for i, digit in enumerate(cardNo[::-1]):
            d = ord(digit) - ord('0')

            # multiply if it's a second digit
            d = d * 2 if i % 2 == 1 else d

            # if digit get's higher than 10 sum the resulting digits
            res += d // 10 + d % 10
         
        return res % 10 == 0