【问题标题】:RegEx and Keyup for Credit Card Detection用于信用卡检测的 RegEx 和 Keyup
【发布时间】:2015-05-02 23:18:53
【问题描述】:

我没有收到来自我整理的信用卡检测 jQuery 的正确输出。 keyup 事件调用一个函数 creditCardTypeFromNumber(num),并且应该检测到信用卡类型。不幸的是,无论输入什么值,返回的唯一内容都是“未知”。我使用过 6011(发现)、5155(万事达卡)和 4147(维萨卡),但都不起作用。

我在这里使用了帖子中每种信用卡类型的 RegEx:

How do you detect Credit card type based on number?

我根据这里所做的将这两个函数放在一起:

Jquery find credit card type

我已经整理了一个 JSFiddle 来显示它不起作用。如果有人可以帮助我,我将不胜感激。谢谢

http://jsfiddle.net/nx6bbjzx/

creditCardTypeAction();

/**
  * Detect Credit Card Type Function
  */
function creditCardTypeAction(){
    $('.creditcardnumber').on('keyup', function(){
        if($(this).val().length >= 4){
            cardType = creditCardTypeFromNumber($(this).val());
        }
    });
}

function creditCardTypeFromNumber(num) {

    // first, sanitize the number by removing all non-digit characters.
    num = num.replace(/[^\d]/g,'');

    // MasterCard
    if (num.match(/^5[1-5][0-9]{5,}$/)) {
        $('.cardsacceptedicon').removeClass('active');
        $('.cardsacceptedicon.mastercard').addClass('active');

        alert('MasterCard');
        return 'MasterCard';

    // Visa
    } else if ( num.match(/^4[0-9]{6,}$/) ) {
        $('.cardsacceptedicon').removeClass('active');
        $('.cardsacceptedicon.visa').addClass('active');

        alert('Visa');
        return 'Visa';

    /* AMEX */
    } else if (num.match(/^3[47][0-9]{5,}$/)) {
        $('.cardsacceptedicon').removeClass('active');
        $('.cardsacceptedicon.amex').addClass('active');

        alert('AMEX');
        return 'AMEX';

    // Discover
    } else if (num.match(/^6(?:011|5[0-9]{2})[0-9]{3,}$/)) {
        $('.cardsacceptedicon').removeClass('active');
        $('.cardsacceptedicon.discover').addClass('active');

        alert('Discover');
        return 'Discover';

    // Diners Club
    } else if (num.match(/^3(?:0[0-5]|[68][0-9])[0-9]{4,}$/)){
        $('.cardsacceptedicon').removeClass('active');
        $('.cardsacceptedicon.diners').addClass('active');

        alert('Diners Club');
        return 'Diners Club';

    // JCB
    } else if (num.match(/^(?:2131|1800|35[0-9]{3})[0-9]{3,}$/)){
        $('.cardsacceptedicon').removeClass('active');
        $('.cardsacceptedicon.jcb').addClass('active');

        alert('JCB');
        return 'JCB';
    }

    alert('UNKNOWN');
    return 'UNKNOWN';
}

【问题讨论】:

  • JSFiddle 似乎找到了正确的卡片类型。什么不工作?
  • 无论我输入什么 4 位数字,每次都会返回 UNKNOWN。我已经在 jsfiddle 中输入了上面的示例数字,并且每次它都向我返回 UNKNOWN。
  • @ScriptsConnect 提供给input 的字符数返回“未知”? “4147”似乎需要七个字符 num.match(/^4[0-9]{6,}$/) 才能返回匹配项?
  • 谢谢@guest271314,这似乎是问题所在。我做的唯一测试是从 4(我在 JSFiddle 中有)切换到 6,但它仍然不适合我。我刚把它切换到 7,现在一切似乎都正常了。
  • @bozdoz,我现在明白你说它找到了正确的卡类型是什么意思。我从来没有输入超过 4 个(当我更改长度时输入了 6 个)并且我没有找到正确的卡片类型。

标签: javascript jquery regex


【解决方案1】:

据我所知,它工作正常。

问题在于您只输入了 4 位数字,这不足以识别卡片 - 那些正则表达式寻找的模式并不那么简单。

例如,尝试输入6011000,您会看到它被标识为“发现”。

您的代码也可以更简洁/可维护:

    function creditCardTypeFromNumber( num ) {
    // Sanitise number
    num = num.replace(/[^\d]/g,'');

    var regexps = {
        'mastercard' : /^5[1-5][0-9]{5,}$/,
        'visa' : /^4[0-9]{6,}$/,
        'amex' : /^3[47][0-9]{5,}$/,
        'discover' : /^6(?:011|5[0-9]{2})[0-9]{3,}$/,
        'diners' : /^3(?:0[0-5]|[68][0-9])[0-9]{4,}$/,
        'jcb' : /^(?:2131|1800|35[0-9]{3})[0-9]{3,}$/,
        'unknown' : /.*/,
    };

    for( var card in regexps ) {
        if ( num.match( regexps[ card ] ) ) {
            console.log( card );
            $( '.cardsacceptedicon' ).removeClass( 'active' );
            $( '.cardsacceptedicon.' + card ).removeClass( 'active' );
            $( 'div.ccvalue' ).html( card );
            return card;
        }
    }
}

这样你就可以通过在“未知”上方粘贴新的正则表达式来添加新卡片:)

【讨论】:

  • 你说得对。在 guest271314 的帖子中,他指出 4147 需要 7 个字符。我对 RegEx 的了解有限,任何时候我需要一个表达式,我只需复制并粘贴它。我只是将其更改为 7 个字符,它适用于所有字符。您是否建议我将所需的最小输入更改为 7 或更多?
  • 你可以,但它并没有真正产生影响,因为较短的输入不会通过任何正则表达式测试。
  • 用建议的代码重写更新了我上面的答案......只是为了好玩,但也让你思考:)
  • 非常感谢 sqrbrkt。这太棒了!您提供给我的内容将帮助我在未来的工作中更好地使用正则表达式!
【解决方案2】:

我不相信您的正则表达式对于您使用它们的方式是正确的?在https://regex101.com/ 试用它们。

路由原因似乎是限定符,例如主卡的 [0-9]{5,} 预计位数在 5 到无限位数之间,这与您输入的内容不匹配。我建议主卡正则表达式可能需要更像^5[1-5][0-9]{2}

【讨论】:

  • 我为每种卡类型使用的 RegEx 来自这里:stackoverflow.com/questions/72768/… 这些值不是很好吗,还有其他更适合信用卡类型的 RegEx 值吗?
  • 该帖子确实非常有用,但看起来他们正在等待输入整个卡号(或至少输入更多),然后再进行验证。你必须自己写这个吗?既然这不是独特的功能,为什么要重新发明轮子……jquerycreditcardvalidator.com
  • 我只想要简单的功能,这样我就可以通过将“活动”类添加到卡片图标来突出显示正确的卡片。我确实同意不要重新发明轮子,但主要是与我已经知道的事情有关。我不知道 RegEx,我需要练习它才能更好地理解它。我会看看你提供的链接。它看起来很有趣。谢谢山姆!
  • 如果您的目标是简单 - 继续使用您的正则表达式,但它们确实需要一些编辑!
【解决方案3】:

信用卡或借记卡的类型是根据数字来确定的。 为此,我们需要将所有输入的数字发送到下面的函数。

getCardType(number) {
  let cards = {
    VISA: /^4[0-9]{12}(?:[0-9]{3})?$/,
    MASTER: /^5[1-5][0-9]{14}$/,
    AEXPRESS: /^3[47][0-9]{13}$/,
    DINERS: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/,
    DISCOVERS: /^6(?:011|5[0-9]{2})[0-9]{12}$/,
    JCB: /^(?:2131|1800|35\d{3})\d{11}$/,
    BCGLOBAL: /^(6541|6556)[0-9]{12}$/,
    INSTAPAYMENT: /^63[7-9][0-9]{13}$/,
    CARTEBLANCHE: /^389[0-9]{11}$/,
    KOREANLOCAL: /^9[0-9]{15}$/,
    LASER: /^(6304|6706|6709|6771)[0-9]{12,15}$/,
    MAESTRO: /^(5018|5020|5038|6304|6759|6761|6763)[0-9]{8,15}$/,
    SOLO: /^(6334|6767)[0-9]{12}|(6334|6767)[0-9]{14}|(6334|6767)[0-9]{15}$/,
    SWITCH: /^(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}$/,
    UNIONPAY: /^(62[0-9]{14,17})$/,
    VISAMASTER: /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})$/
  };

  for (var card in cards) {
    if (cards[card].test(number)) {
      return card;
    } else {
      return 'INVALID'
    }
  }
}

此函数将返回卡的类型。 尝试一下。享受吧!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-30
    • 2014-08-05
    • 2011-01-22
    • 1970-01-01
    • 2013-09-21
    • 2013-02-16
    • 1970-01-01
    • 2014-02-27
    相关资源
    最近更新 更多