2015-01-29 4 views
7

Я действительно новичок в регулярном выражении, но думаю, что моя проблема может выйти за рамки этого в настоящий момент. Как говорит название, я пытаюсь определить, если кредитная карта Visa, Amex, мастер-карты и т.д.Regex для определения кредитных карт в Android

Я смотрел на этот пост, который дал регулярное выражение для каждого из типов карт:

How do you detect Credit card type based on number?

Это код, который я тогда использовал, но это ничего не делать вообще:

etCCNum.addTextChangedListener(new TextWatcher() { 
      @Override 
      public void onTextChanged(CharSequence s, int start, int before, int count) { 



      } 

      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
       Log.d("DEBUG", "beforeTextChanged : "+s); 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 
       Pattern pattern = Pattern.compile("^6(?:011|5[0-9]{2})[0-9]{3,}$"); 
       Log.d("DEBUG", "afterTextChanged : "+s); 
       String ccNum = s.toString(); 
       Matcher matcher = pattern.matcher(ccNum); 
       if(matcher.matches()){ 
        Log.d("DEBUG", "afterTextChanged : discover"); 
       } 

      } 
     }); 

Регулярное выражение в функции Pattern.compile для определения Discover карты в соответствии с пост выше. Я заметил, что я действительно не могу заставить ничего работать, кроме «^» в регулярном выражении (т. Е. («^ 4» - visa, «^ 6001»), однако этого явно недостаточно для редактирования Я думал, что это может быть проблемой с моей Java, но я запускаю Java 7

Возможно, я хочу задать новый вопрос, но мне также интересно, как можно использовать регулярное выражение для получения интервал, правильный для различных кредитных карт, даже если пользователь возвращается и редактирует номер (xxxx xxxx xxxx xxxx)

EDIT: Добавлен журнал DEBUG сверху. Мой ввод - это несколько цифр, которые должны ассоциироваться с определенными кредитными картами. Я использую приведенный ниже код Eagle Eye (который также должен работать для обнаружения того, что вход является ОДИН из типов карт):

final ArrayList listOfPattern = new ArrayList();

String ptVisa = "^4[0-9]{6,}$"; 
listOfPattern.add(ptVisa); 
String ptMasterCard = "^5[1-5][0-9]{5,}$"; 
listOfPattern.add(ptMasterCard); 
String ptAmeExp = "^3[47][0-9]{5,}$"; 
listOfPattern.add(ptAmeExp); 
String ptDinClb = "^3(?:0[0-5]|[68][0-9])[0-9]{4,}$"; 
listOfPattern.add(ptDinClb); 
String ptDiscover = "^6(?:011|5[0-9]{2})[0-9]{3,}$"; 
listOfPattern.add(ptDiscover); 
String ptJcb = "^(?:2131|1800|35[0-9]{3})[0-9]{3,}$"; 
listOfPattern.add(ptJcb); 


etCCNum.addTextChangedListener(new TextWatcher() { 
    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 



    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     Log.d("DEBUG", "beforeTextChanged : "+s); 

    } 

    @Override 
    public void afterTextChanged(Editable s) { 
     Log.d("DEBUG", "afterTextChanged : "+s); 
     String ccNum = s.toString(); 
     for(String p:listOfPattern){ 
      if(ccNum.matches(p)){ 
       Log.d("DEBUG", "afterTextChanged : discover"); 
       break; 
      } 
     } 

    } 
}); 

Log:

01-29 15:16:41.932 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 
01-29 15:16:41.933 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 4 
01-29 15:16:46.815 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 4 
01-29 15:16:46.816 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 
01-29 15:16:50.925 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 
01-29 15:16:50.926 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 6 
01-29 15:16:51.542 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 6 
01-29 15:16:51.543 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 60 
01-29 15:16:51.883 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 60 
01-29 15:16:51.883 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 600 
01-29 15:16:52.928 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 600 
01-29 15:16:52.929 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 6001 
01-29 15:16:55.781 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 6001 
01-29 15:16:55.782 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 600 
01-29 15:16:56.206 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 600 
01-29 15:16:56.206 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 60 
01-29 15:16:57.659 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 60 
01-29 15:16:57.660 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 605 
01-29 15:16:59.297 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 605 
01-29 15:16:59.298 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 60 
01-29 15:16:59.527 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 60 
01-29 15:16:59.527 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 6 
01-29 15:17:00.314 26194-26194/com.x.x D/DEBUG﹕ beforeTextChanged : 6 
01-29 15:17:00.314 26194-26194/com.x.x D/DEBUG﹕ afterTextChanged : 65 

Вы ожидали бы, что журнал «открыть», чтобы выйти несколько раз для разных цифр я введенными. В приведенном выше журнале показано, как я печатаю первые несколько цифр карточки визы и карты для обнаружения.

EDIT ANSWER FOUND: Я просто не печатал достаточно цифр для распознаваемой карты!

+0

у вас связаны с вопросом, который полностью отвечает на различные аспекты вашего вопроса. – njzk2

+0

Мой вопрос: почему этот код не работает для меня. Я думаю, что проблема связана с Java или андроид-студией – AIntel

+0

опубликовать ваш журнал. Какой вклад вы пытаетесь сопоставить с этим регулярным выражением? – njzk2

ответ

14

Согласно одному из ответов в теме, карты могут быть подтверждены на основании следующих данных.

Visa: номера ^4[0-9]{6,}$ Visa карты начинаются с 4.

MasterCard:^5[1-5][0-9]{5,}$ номера MasterCard начинаются с цифры 51 по 55, но это будет только обнаружить кредитные карты MasterCard; есть другие карты, выпущенные с использованием системы MasterCard, которые не попадают в этот диапазон IIN.

American Express: номера ^3[47][0-9]{5,}$ American Express карты начинаются с 34 или 37.

Diners Club:^3(?:0[0-5]|[68][0-9])[0-9]{4,}$ Diners Club номера карт начинаются с 300 по 305, 36 или 38. Есть Diners Club карты, которые начинаются с 5 и имеют 16 цифр. Это совместное предприятие Diners Club и MasterCard и должно обрабатываться как MasterCard.

Discover: номера ^6(?:011|5[0-9]{2})[0-9]{3,}$ Discover карты начинаются с 6011 или 65

JCB:^(?:2131|1800|35[0-9]{3})[0-9]{3,}$ JCB карты начинаются с 2131, 1800 или 35.

Так что вам нужно создать отдельный шаблон для каждого дело. Вы можете сделать следующее.

ArrayList<String> listOfPattern=new ArrayList<String>(); 

String ptVisa = "^4[0-9]{6,}$"; 
listOfPattern.add(ptVisa); 
String ptMasterCard = "^5[1-5][0-9]{5,}$"; 
listOfPattern.add(ptMasterCard); 
String ptAmeExp = "^3[47][0-9]{5,}$"; 
listOfPattern.add(ptAmeExp); 
String ptDinClb = "^3(?:0[0-5]|[68][0-9])[0-9]{4,}$"; 
listOfPattern.add(ptDinClb); 
String ptDiscover = "^6(?:011|5[0-9]{2})[0-9]{3,}$"; 
listOfPattern.add(ptDiscover); 
String ptJcb = "^(?:2131|1800|35[0-9]{3})[0-9]{3,}$"; 
listOfPattern.add(ptJcb); 
} 

, а затем,

@Override 
public void afterTextChanged(Editable s) { 
Log.d("DEBUG", "afterTextChanged : "+s); 
String ccNum = s.toString(); 
    for(String p:listOfPattern){ 
     if(ccNum.matches(p)){ 
     Log.d("DEBUG", "afterTextChanged : discover"); 
     break; 
     } 
    } 
} 

И ваш последний вопрос, следующая нить должна помочь вам.

Format credit card in edit text in android

EDIT:

Если номер карты состоит из 16 цифр, например, после применения логики для добавления пробела после 4-х цифр, вам необходимо удалить эти пробелы при обработке фактической карты номер. Тогда будет работать только вышеприведенная логика.

Надеюсь, это поможет.

+0

Это не работает для меня. Он никогда не входит в оператор if. – AIntel

+0

Извини, мой плохой. Обновите ответ. Вам нужно удалить добавленные пробелы из номера карты. – EagleEye

+1

Пока вы правы, не должно быть пробелов, я печатаю кредитную карточку без пробелов и все равно не работает. Есть ли вероятность, что определенное регулярное выражение не работает на Java 7? – AIntel

0

Используйте следующий класс для подтверждения вашей карты.

public class Validator { 


public static final byte VISA = 0; 
public static final byte MASTERCARD = 1; 
public static final byte AMEX = 2; 
public static final byte DINERS_CLUB = 3; 
public static final byte CARTE_BLANCHE = 4; 
public static final byte DISCOVER = 5; 
public static final byte ENROUTE = 6; 
public static final byte JCB = 7; 

public static boolean validate(final String credCardNumber, final byte type) { 
    String creditCard = credCardNumber.trim(); 
    boolean applyAlgo = false; 
    switch (type) { 
     case VISA: 
      // VISA credit cards has length 13 - 15 
      // VISA credit cards starts with prefix 4 
      if (creditCard.length() >= 13 && creditCard.length() <= 16 
        && creditCard.startsWith("4")) { 
       applyAlgo = true; 
      } 
      break; 
     case MASTERCARD: 
      // MASTERCARD has length 16 
      // MASTER card starts with 51, 52, 53, 54 or 55 
      if (creditCard.length() == 16) { 
       int prefix = Integer.parseInt(creditCard.substring(0, 2)); 
       if (prefix >= 51 && prefix <= 55) { 
        applyAlgo = true; 
       } 
      } 
      break; 
     case AMEX: 
      // AMEX has length 15 
      // AMEX has prefix 34 or 37 
      if (creditCard.length() == 15 
        && (creditCard.startsWith("34") || creditCard 
        .startsWith("37"))) { 
       applyAlgo = true; 
      } 
      break; 
     case DINERS_CLUB: 
     case CARTE_BLANCHE: 
      // DINERSCLUB or CARTEBLANCHE has length 14 
      // DINERSCLUB or CARTEBLANCHE has prefix 300, 301, 302, 303, 304, 
      // 305 36 or 38 
      if (creditCard.length() == 14) { 
       int prefix = Integer.parseInt(creditCard.substring(0, 3)); 
       if ((prefix >= 300 && prefix <= 305) 
         || creditCard.startsWith("36") 
         || creditCard.startsWith("38")) { 
        applyAlgo = true; 
       } 
      } 
      break; 
     case DISCOVER: 
      // DISCOVER card has length of 16 
      // DISCOVER card starts with 6011 
      if (creditCard.length() == 16 && creditCard.startsWith("6011")) { 
       applyAlgo = true; 
      } 
      break; 
     case ENROUTE: 
      // ENROUTE card has length of 16 
      // ENROUTE card starts with 2014 or 2149 
      if (creditCard.length() == 16 
        && (creditCard.startsWith("2014") || creditCard 
        .startsWith("2149"))) { 
       applyAlgo = true; 
      } 
      break; 
     case JCB: 
      // JCB card has length of 16 or 15 
      // JCB card with length 16 starts with 3 
      // JCB card with length 15 starts with 2131 or 1800 
      if ((creditCard.length() == 16 && creditCard.startsWith("3")) 
        || (creditCard.length() == 15 && (creditCard 
        .startsWith("2131") || creditCard 
        .startsWith("1800")))) { 
       applyAlgo = true; 
      } 
      break; 
     default: 
      throw new IllegalArgumentException(); 
    } 
    if (applyAlgo) { 
     return validate(creditCard); 
    } 
    return false; 
} 

public static boolean validate(String creditCard) { 
    // 4 9 9 2 7 3 9 8 7 1 6 
    // 6 
    // 1 x 2 = 2 = (0 + 2) = 2 
    // 7 
    // 8 x 2 = 16 = (1 + 6) = 7 
    // 9 
    // 3 x 2 = 6 = (0 + 6) = 6 
    // 7 
    // 2 x 2 = 4 = (0 + 4) = 4 
    // 9 
    // 9 X 2 = 18 = (1 + 8) = 9 
    // 4 
    // 6+2+7+7+9+6+7+4+9+9+4 = 70 
    // return 0 == (70 % 10) 
    int sum = 0; 
    int length = creditCard.length(); 
    for (int i = 0; i < creditCard.length(); i++) { 
     if (0 == (i % 2)) { 
      sum += creditCard.charAt(length - i - 1) - '0'; 
     } else { 
      sum += sumDigits((creditCard.charAt(length - i - 1) - '0') * 2); 
     } 
    } 
    return 0 == (sum % 10); 
} 

private static int sumDigits(int i) { 
    return (i % 10) + (i/10); 
} 



public final static boolean isValidEmail(CharSequence target) { 
    return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches(); 
} 

}

+0

Переменная 'applyAlgo' в основном избыточна, поскольку вы генерируете исключение, когда большинство путей, которые устанавливают его в 'true', не принимаются, и это не помешает применить его в других случаях. Я также жестоко против абстрагирования этого слова. Слово «алгоритм», от собственного имени. – EJP

+1

Это не то, что я пытаюсь сделать, я пытаюсь выяснить, какой тип кредитной карты вводится, когда пользователь печатает. Я уже применяю алгоритм проверки, чтобы определить, действительна ли кредитная карта. – AIntel

+0

'// Кредитные карты VISA имеют длину 13 - 15'. Нет. – njzk2

Смежные вопросы