2012-11-21 7 views
8

Przeczytałem przez this question, ale w przypadku karty Discover cyfry początkowe to 6011, 622126-622925, 644-649, 65 zamiast tylko 6011, 65. (Source)Regex for Discover credit card

Dla kart Discover, podniosłem ten regex z tym pytaniem ^6(?:011|5[0-9]{2})[0-9]{12}$

I zmodyfikowanego to na pokrycie 6011, 644-649 & 65 ale 622126-622925, regex budowy jest trudne bo moje słabe umiejętności regex.

Mam to wyrażenie do tej pory 6(?:011|5[0-9]{2}|[4][4-9][0-9]|[2]{2}[1-9])[0-9]{2}$, ale sprawdza tylko dla 622[1-9]**.

Jak mogę go zmodyfikować, aby był akceptowany tylko między 622126-622925 dla przypadku 622***?

+0

Czy możesz po prostu użyć normalnego Discover Regex i wykonać kontrolę w bardziej czytelny sposób w następnej linii? –

+0

Każdy powód, dla którego nie użyjesz tylko porównań liczb nieregexowych? – djechlin

+0

@YuriyFaktorovich Niestety cię nie dostałem. Masz na myśli sformatowanie mojego pytania powyżej lub rozwiązanie go w 2 krokach? Jeśli to ostatnie, wolałbym za to jedno wyrażenie regularne. – Ashfame

Odpowiedz

9

Oto Twój regex (demo):

^6(?:011\d{12}|5\d{14}|4[4-9]\d{13}|22(?:1(?:2[6-9]|[3-9]\d)|[2-8]\d{2}|9(?:[01]\d|2[0-5]))\d{10})$ 

trzeba dodawać, że nie będę dokładnie nazwać całkiem lub proste utrzymać. Poleciłbym analizowanie liczby jako liczby całkowitej i używanie języka programowania do przeprowadzania kontroli.

Należy również używać Luhn algorithm aby sprawdzić, czy numer karty kredytowej jest ważne, a jednocześnie można teoretycznie zrobić to z regex, by wiele razy gorzej niż ten to.


Pozwól, że pokażę Ci, jak przybyłem do tego potwora, krok po kroku. Po pierwsze, tutaj jest jak dopasować każdy z tych zakresów:

6011  # matches 6011 
65   # matches 65 
64[4-9]  # matches 644-649 
622(1(2[6-9]|[3-9]\d)|[2-8]\d{2}|9([01]\d|2[0-5])) 
      # matches 622126-622925 

Teraz chcesz dopasować resztę cyfr:

6011\d{12}  # matches 6011 + 12 digits 
65\d{14}   # matches 65 + 14 digits 
64[4-9]\d{13}  # matches 644-649 + 13 digits 
622(1(2[6-9]|[3-9]\d)|[2-8]\d{2}|9([01]\d|2[0-5]))\d{10} 
        # matches 622126-622925 + 10 digits 

Teraz można połączyć wszystkie cztery, a dodać początek i koniec linii zakotwicza:

^(     # match start of string and open group 
6011\d{12}|  # matches 6011 + 12 digits 
65\d{14}|   # matches 65 + 14 digits 
64[4-9]\d{13}|  # matches 644-649 + 13 digits 
622(1(2[6-9]|[3-9]\d)|[2-8]\d{2}|9([01]\d|2[0-5]))\d{10} 
        # matches 622126-622925 + 10 digits 
)$     # close group and match end of string 

Produkt końcowy powyżej jest lekko zagęszczony wersja poprzedniego regex, a ja również grupy nie przechwytywania (to co ci ?: dotyczą).

+0

Święty shmoly! Teraz widzę, jak to się skomplikowało i poza tym, co rozumiem. Właśnie zrobiłem to działa, analizując go jako liczbę całkowitą i porównując go dla przypadku '622126-622925'. Dzięki Nerdlord za wyjaśnienie mi tego! : D – Ashfame

+0

@Ahfame Tak, zakresy w wyrażeniu regularnym stają się nieporęczne szybko. I tak jak powiedziałem, powinieneś również sprawdzić, czy cyfra kontrolna jest prawidłowa; i to jest coś, do czego naprawdę * nie powinieneś używać wyrażeń regularnych. – NullUserException

+0

Tak, proszę pana! Mam wtyczkę sprawdzania poprawności jQuery dla algorytmu Luhn w tym celu. – Ashfame

0

Oto opcje:

  1. Hack swoją drogę przez to i zbudować naprawdę skomplikowane wyrażenia regularnego. Regeksy nie nadają się do tego rodzaju porównania liczb całkowitych, więc to, co wymyślisz, będzie z konieczności długie, nieskomplikowane i niemożliwe do opanowania. Zobacz Regex for number check below a value i podobne pytania dotyczące SO na ten temat.
  2. Użyj porównania liczb całkowitych w kodzie.

Dla porównania jeden taki powiedział skomplikowane regex byłoby

62212[6-9]|6221[3-9]|622[1-8]|62291|62292[1-5]

0

nawet ten bilet to 3 lata temu, natknąłem to samo zadanie i chciałbyś podzielić regex dla 622126-622925 :)

^(622[1-9]\\d(?<!10|11|9[3-9])\\d(?<!12[0-5]|92[6-9])\\d{10})$ 

który zerowej szerokości negatywny lookbehind aby wykluczyć nie oczekuje liczba