Regex para determinar las tarjetas de crédito en Android

Soy realmente nuevo para regex, pero creo que mi problema podría ir más allá de eso en este momento. Como dice el título, estoy tratando de determinar si una tarjeta de crédito es visa, amex, tarjeta maestra, etc.

Miré este post que dio la expresión regular para cada uno de los tipos de tarjeta:

¿Cómo detecta el tipo de tarjeta de crédito basado en el número?

Éste es el código que utilicé entonces pero no hace absolutamente nada:

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"); } } }); 

El regexp en la función pattern.compile es para determinar las tarjetas Discover de acuerdo con la entrada anterior. He notado que realmente no puedo conseguir nada que funcione aparte del "^" en regex (es decir ("^ 4" – visa, "^ 6001" discover) sin embargo esto obviamente no es suficiente en el caso de la edición para Por ejemplo, ¿cuáles son las ideas ?, pensé que esto podría ser un problema con mi Java, pero estoy ejecutando Java 7

Es posible que quiera hacer de esto una nueva pregunta, pero también me estoy preguntando cómo regex puede ser utilizado para obtener el espaciamiento correcto para varias tarjetas de crédito, incluso si un usuario vuelve y edita el número (xxxx xxxx xxxx xxxx)

EDIT: Añadido el registro DEBUG desde arriba. Mi entrada es algunos dígitos que deben asociarse con ciertas tarjetas de crédito. Actualmente utilizo el código de Eagle Eye proporcionado a continuación (que también debería funcionar para detectar que la entrada es UNO de los tipos de tarjeta):

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; } } } }); 

Iniciar sesión:

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

Es de esperar que el registro "discover" salga varias veces para los diferentes dígitos que he ingresado. El registro anterior me muestra escribiendo los primeros dígitos de una tarjeta Visa y una tarjeta de descubrimiento.

EDITAR RESPUESTA ENCONTRADA: Simplemente no estaba escribiendo en dígitos suficientes para la tarjeta de ser reconocido!

Según una de las respuestas en el hilo, Las tarjetas pueden ser validadas basándose en los siguientes datos.

Visa: ^4[0-9]{6,}$ Los números de la tarjeta Visa comienzan con un 4.

MasterCard: ^5[1-5][0-9]{5,}$ números MasterCard comienzan con los números 51 a 55, pero esto solo detectará las tarjetas de crédito MasterCard; Hay otras tarjetas emitidas usando el sistema MasterCard que no caen dentro de este rango IIN.

American Express: ^3[47][0-9]{5,}$ Los números de tarjeta American Express comienzan con 34 o 37.

Diners Club: ^3(?:0[0-5]|[68][0-9])[0-9]{4,}$ números de la tarjeta de Diners Club comienzan con 300 a 305, 36 ó 38. Tarjetas Diners Club que comienzan con 5 y tienen 16 dígitos. Se trata de una empresa conjunta entre Diners Club y MasterCard, y debe ser procesado como una MasterCard.

Descubre: ^6(?:011|5[0-9]{2})[0-9]{3,}$ Descubra los números de las tarjetas comienzan con 6011 ó 65.

JCB: ^(?:2131|1800|35[0-9]{3})[0-9]{3,}$ tarjetas JCB empiezan con 2131, 1800 o 35.

Por lo tanto, necesita crear patrones separados para cada caso. Puede hacer lo siguiente.

 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); } 

y entonces,

 @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; } } } 

Y para su última pregunta, el siguiente hilo le ayudará.

Formato de tarjeta de crédito en editar texto en android

EDITAR:

Si el número de la tarjeta es de 16 dígitos, por ejemplo, Después de aplicar la lógica para agregar espacios después de 4 dígitos, debe quitar esos espacios cuando procese el número de tarjeta real. Entonces sólo funcionará la lógica anterior.

Espero que esto ayude.

Utilice la siguiente clase para validar su tarjeta.

 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(); } 

}

  • ¿Cómo puedo crear una expresión regular para esto en android?
  • Regex no funciona en Android pero funciona bien en Java
  • Expresión regular para eliminar todos los caracteres no imprimibles
  • Manejo de spoiler BBcode Android
  • Java.util.regex.PatternSyntaxException en Android
  • Fuerza de cierre en la expresión regular!
  • Identificar el tipo de patrón de regex
  • ¿Cómo usar los marcadores de principio y fin en regex para Java String?
  • PHP - RegEx Números de teléfono con o sin código de país
  • Diferencia de regex de Java y Android
  • ¿Cómo validar una cadena usando java regex?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.