This question already has answers here:
How do you detect Credit card type based on number?

(30个答案)


6年前关闭。




我对regex确实很陌生,但我认为目前的问题可能不止于此。如标题所述,我正在尝试确定信用卡是否是签证,美国运通卡,万事达卡等。

我看了这篇帖子,给出了每种卡类型的正则表达式:

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函数中的regexp用于根据上述内容确定Discover卡。我已经注意到,除了正则表达式中的“^”以外,我真的无法工作(例如(“^ 4”-签证,“^ 6001”发现),但是在编辑以下内容时显然这是不够的例如,有什么想法吗?我以为这可能是Java的问题,但是我正在运行Java 7

我可能想提出一个新问题,但我也想知道,即使用户返回并编辑号码(xxxx xxxx xxxx xxxx),如何使用正则表达式来正确校正各种信用卡的间距

编辑:从上面添加了调试日志。我的输入是应该与某些信用卡关联的一些数字。目前,我正在使用下面提供的Eagle Eye的代码(也可以用于检测输入是否为卡类型之一):

最终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.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

您可能希望针对我输入的不同数字多次出现“发现”日志。上面的日志显示我输入了签证卡和发现卡的前几个数字。

编辑答复:我只是没有输入足够的数字来识别该卡!

最佳答案

根据线程中的答案之一,可以基于以下数据来验证卡。

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

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

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

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

发现: ^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开头。

因此,您需要为每种情况创建单独的模式。您可以执行以下操作。

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

编辑:

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

希望这可以帮助。

08-18 10:28