title: Regex for determining credit cards in Android
body: <p>I'm really new to regex but I think my problem might go beyond that at the moment. As the title says, I'm trying to determine if a credit card is visa, amex, master card etc. </p>
  
  <p>I looked at this post which gave the regular expression for each of the card types:</p>
  
  <p><a href="https://stackoverflow.com/questions/72768/how-do-you-detect-credit-card-type-based-on-number">How do you detect Credit card type based on number?</a></p>
  
  <p>This is the code I then used but it doesn't do anything at all:</p>
  
  <pre><code>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");
                 }
  
              }
          });
  </code></pre>
  
  <p>The regexp in the pattern.compile function is for determining Discover cards according to the post above. I've noticed that I really can't get anything to work other than the "^" in regex (i.e ("^4" - visa, "^6001" discover) however this is obviously not sufficient in the case of editing for example. Any ideas what's up? I thought this could be an issue with my Java, but I am running Java 7</p>
  
  <p>I might want to make this a new question, but I am also wondering how regex can be used to get spacing correct for various credit cards even if a user goes back and edits the number (xxxx xxxx xxxx xxxx)</p>
  
  <p>EDIT: Added the DEBUG log from above. My input is a few digits that should associate with certain credit cards. Currently I am using Eagle Eye's code provided below (which should also work for detecting that the input is ONE of the card types):</p>
  
  <p>final ArrayList listOfPattern=new ArrayList();</p>
  
  <pre><code>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;
              }
          }
  
      }
  });
  </code></pre>
  
  <p>Log:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>You'd expect the log "discover" to come out a few times for the different digits I've entered. The above log shows me typing in the first few digits of a visa card and a discover card.</p>
  
  <p>EDIT ANSWER FOUND: I simply wasn't typing in enough digits for the card to be recognized!</p>