用于确定Android中的信用卡的正则expression式

对于正则expression式我真的很陌生,但我认为我的问题现在可能会超越这个问题。 正如标题所说,我试图确定信用卡是否是签证,美国运通,主卡等。

我看了这个post,给出了每种卡types的正则expression式:

如何根据数字检测信用卡types?

这是我然后使用的代码,但它什么也没有做:

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函数中的正则expression式用于根据上面的post确定发现卡片。 我注意到除了正则expression式中的“^”之外,我实在无法得到任何东西(例如(“^ 4” – visa,“^ 6001”discover)),但是在编辑的情况下显然是不够的例如,任何想法是什么?我认为这可能是我的Java的问题,但我正在运行Java 7

我可能想这是一个新的问题,但我也想知道如何正则expression式可以用来获取各种信用卡正确的间距,即使用户回去编辑数字(xxxx xxxx xxxx xxxx)

编辑:添加从上面的DEBUG日志。 我的input是几个数字,应该与某些信用卡相关联。 目前我正在使用下面提供的Eagle Eye的代码(这也应该用于检测input是哪一种卡types):

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

日志:

 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 

你会希望日志“发现”出来几次我input的不同数字。 上面的日志显示我在签证卡和发现卡的前几位input。

编辑答案发现:我只是没有input足够的数字来识别卡!

Solutions Collecting From Web of "用于确定Android中的信用卡的正则expression式"

根据线程中的答案之一,卡可以基于以下数据进行validation。

签证: ^4[0-9]{6,}$ Visa卡号以4开头。

万事达卡: ^5[1-5][0-9]{5,}$万事达卡号码以51到55开头,但这只能检测到万事达信用卡。 还有其他使用MasterCard系统发行的卡不属于这个IIN范围。

美国运通: ^3[47][0-9]{5,}$美国运通卡号码以34或37开头。

大来卡: ^3(?:0[0-5]|[68][0-9])[0-9]{4,}$ Diners Club卡号以300到305,36或38开头。大来卡以5开头,有16位数字。 这是Diners Club和MasterCard的合资企业,应该像万事达卡一样处理。

发现: ^6(?:011|5[0-9]{2})[0-9]{3,}$发现卡号以6011或65开头。

JCB: ^(?:2131|1800|35[0-9]{3})[0-9]{3,}$ JCB卡以2131,1800或35开头。

所以你需要为每个案例创build单独的模式。 你可以做如下。

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

而对于你最后的问题,下面的线程应该可以帮助你。

在android中编辑文本格式的信用卡

编辑:

例如,如果卡号是16位,则在应用逻辑在4位后添加空格后,在处理实际卡号时需要删除这些空格。 那么只有上面的逻辑会起作用。

希望这可以帮助。

使用下面的课程来validation你的卡。

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

}