2012-08-11 11 views
5

Piszę narzędzie, które onkeydown uruchomi bieżącą wartość wprowadzaną w polu wejściowym, aby sprawdzić, czy pasuje do wyrażenia regularnego dla jednego z 4 głównych typów kart kredytowych.Przewidywanie karty kredytowej w JavaScript

Czuję, że to działa, ale jest niestabilny, więc chciałem dowiedzieć się, co było przyczyną tego, aby dać błędną odpowiedź (np. Czasami będzie to wynik 2 wartości zamiast jednej). Czy to dlatego, że przed zapętleniem muszę ustawić zmienną flagi? Po meczu właściwej karty, po prostu powrocie z pętli przez obiekt, więc pomyślałem, że byłoby wystarczające ...

kryteria dla regexes wyciągali z this site:

  • Visa: ^4[0-9]{12}(?:[0-9]{3})?$ Wszystkie numery kart Visa zaczynają się od 4. Nowe karty mają 16 cyfr. Stare karty mają 13.

  • MasterCard: ^5[1-5][0-9]{14}$ Wszystkie numery MasterCard rozpoczynają się cyframi od 51 do 55. Wszystkie mają 16 cyfr.

  • American Express: ^3[47][0-9]{13}$ Numery kart American Express zaczynają się od 34 lub 37 i mają 15 cyfr.

  • Odkryj: ^6(?:011|5[0-9]{2})[0-9]{12}$ Odczytaj numery kart zaczynają się od 6011 lub 65. Wszystkie mają 16 cyfr.

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

robisz coś złego gdzie indziej. Po zalogowaniu do konsoli kończymy procedurę/kończymy pętlę, więc nie ma szansy na wyprowadzenie dwóch linii dziennika. – SJuan76

+0

Sprawdź to http://en.wikipedia.org/wiki/Luhn. A następnie ta implementacja to JS https://github.com/jzaefferer/jquery-validation/blob/master/jquery.validate.js#L1129 – elclanrs

+0

nie wymyślaj ponownie koła;) – jantimon

Odpowiedz

4

Wydaje się, że używasz wyrażeń regularnych w niewłaściwy sposób.

Jeśli chcesz sprawdzić ciąg przeciwko wyrażenia regularnego, można użyć metody match() napisu:

string.match(regexp) // returns boolean 

robisz to w niewłaściwy sposób:

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

próbuje interpretować bieżącą wartość jako wyrażenie regularne. Musi być w ten sposób:

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

Można także buforować wyrażeń regularnych, aby skrypt bardziej efektywne:

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. Dzięki ... Tak, to ma sens w przechowywaniu samego regex zamiast ciągu. Dzięki za szybką odpowiedź :) –

+0

Uważam, że 'match' jest mylące, ponieważ każda inna metoda regexp działa na regex i' match' działa na łańcuchu. Zawsze używam 'exec' zamiast' match' z tego powodu -> 'regex.exec ($ (this) .val())' – elclanrs

Powiązane problemy