2012-08-11 25 views
5

Estoy escribiendo una herramienta que onkeydown ejecutará el valor actual ingresado en un cuadro de entrada para verificar si coincide con una expresión regular para uno de los 4 tipos principales de tarjetas de crédito.Predicción de tarjeta de crédito en Javascript

Parece que funciona, pero es escamosa, así que quería saber qué causaba una respuesta incorrecta (por ejemplo, algunas veces generará 2 valores en lugar de uno). ¿Es porque necesito establecer una variable de indicador antes de hacer bucles? Al partido de la tarjeta correcta, sólo estoy volviendo desde el bucle a través del objeto, así que pensé que eso sería suficiente ...

Los criterios para las expresiones regulares fueron sacados de this site:

  • Visa: ^4[0-9]{12}(?:[0-9]{3})?$ Todos los números de tarjeta Visa comienzan con 4. Las tarjetas nuevas tienen 16 dígitos. tarjetas de edad tienen 13.

  • MasterCard: ^5[1-5][0-9]{14}$ Todos los números de MasterCard comenzar con los números 51 a 55. Todos tienen 16 dígitos.

  • American Express: ^3[47][0-9]{13}$ Los números de la tarjeta American Express comienzan con 34 o 37 y tienen 15 dígitos.

  • Descubre: ^6(?:011|5[0-9]{2})[0-9]{12}$ Descubre los números de tarjeta comienzan con 6011 o 65. Todos tienen 16 dígitos.

    $(function() { 
    
    var $cardNumber = $('#js-cardnumber'); 
    
    var ccMap = {}; 
    
    ccMap.cards = { 
        'amex': '^3[47][0-9]{13}$', 
        'discover': '^6(?:011|5[0-9]{2})[0-9]{12}$', 
        'mastercard': '^5[1-5][0-9]{14}$', 
        'visa': '^4[0-9]{12}(?:[0-9]{3})?$' 
    }; 
    
    
    $cardNumber.keydown(function() { 
    for (var cardType in ccMap.cards) { 
        if (ccMap.cards.hasOwnProperty(cardType)) { 
         var regex = ccMap.cards[cardType]; 
         if (regex.match($(this).val())) { 
          console.log(cardType); 
          return; 
         } 
        } 
    } 
    }); 
    });​ 
    

Here's a fiddle

+0

Usted está haciendo algo mal en otras partes. Después de iniciar sesión en la consola, está saliendo del procedimiento/finalizando el ciclo, por lo que no hay posibilidad de que se generen dos líneas de registro. – SJuan76

+0

Mira esto http://en.wikipedia.org/wiki/Luhn. Y luego esta implementación es JS https://github.com/jzaefferer/jquery-validation/blob/master/jquery.validate.js#L1129 – elclanrs

+0

no reinventar la rueda;) – jantimon

Respuesta

4

Parece que estás usando las expresiones regulares de una manera incorrecta.

Si desea comprobar una cadena con una expresión regular, puede utilizar el método match() de la cadena:

string.match(regexp) // returns boolean 

Lo estás haciendo de manera equivocada:

if (regex.match($(this).val())) { 

intentos interpretar el valor actual como una expresión regular. Debe ser de esta manera:

if ($(this).val().match(regex)) { 

También puede almacenar en caché las expresiones regulares para hacer su escritura más eficiente:

ccMap.cards = { 
    'amex': /^3[47][0-9]{13}$/, // store an actual regexp object, not a string 
    // ... 

// The way you test changes, now you're able to use the "test" 
// method of the regexp object: 
if (regex.test($(this).val())) { 
+0

Oh dang. Gracias ... Sí, tiene mucho más sentido almacenar la expresión regular en lugar de una cadena. Gracias por la respuesta rápida :) –

+0

Encuentro 'match' confuso porque cada otro método de expresión regular funciona en la expresión regular y' match' funciona en una cadena. Siempre uso 'exec' en lugar de' match' por este motivo -> 'regex.exec ($ (this) .val())' – elclanrs

Cuestiones relacionadas