1

I simply have a program that must read a ssn (xxx-xx-xxxx) and determine if the given ssn is valid. I just need a way to check that the string only contains #'s and -'s.

import java.util.Scanner;
public class Prog7 {
  public static void main(String[] args) {

  Scanner input = new Scanner(System.in);
  System.out.print("Enter a SSN:");
  String ssn = input.next();

  if((ssn.substring(0, 4).indexOf('-') != 3) || (ssn.substring(4, 7).indexOf('-') != 2) || 
     (ssn.substring(ssn.length() - 5, ssn.length()).indexOf('-') != 0) ) {
     System.out.println(ssn + " is an invalid social security number");
  }
  else {
    System.out.println(ssn + " is a valid social security number");
  }

  }
}
Drizzles
  • 41
  • 1
  • 2
  • Seems a little over complicated. You could split the string around `-`s, check the substrings size and if they're #s. – ChiefTwoPencils Oct 17 '16 at 23:05
  • 1
    http://stackoverflow.com/questions/29764731/verifying-if-an-input-string-is-a-correct-social-security-number – Reimeus Oct 17 '16 at 23:10

3 Answers3

3

Regular expression representing xxx-xx-xxxx where x stands for digit can be written as \d\d\d-\d\d-\d\d\d\d (note: \ in String literals is special character, so if you want to use it as symbol and pass to regex engine you will need to escape it with another \, so String literal representing \d needs to be written as "\\d").

Now you can simply use yourString.matches(regex) to see if regex matches whole yourString

So simple

String ssn = input.next();

if(ssn.matches("\\d\\d\\d-\\d\\d-\\d\\d\\d\\d")){
    //here we know that `snn` is valid
}

should work fine.

Improvements:

You can make your regex more readable by using quantifiers. For instance with {n} we can express how many times previous element must appear. So instead of \d\d\d we can write \d{3}.

Also Scanner has methods which support regex, like hasNext(regex) to check if next token can be matched by regex. If it is not, we can simply consume it using next() and ask for new value:

System.out.print("Enter a SSN:");
while(!input.hasNext("\\d{3}-\\d{2}-\\d{4}")){
    String invalid = input.next();
    System.out.print(invalid + " is not valid SSN. Please try again:");
}
//here we are sure that data provided by user represent valid SSN
String ssn = input.next();
Pshemo
  • 122,468
  • 25
  • 185
  • 269
0

Use a regular expression:

String ssn = input.next();
String pattern = "[0-9]{3}-[0-9]{2}-[0-9]{4}";
Pattern p = Pattern.compile(pattern);

Matcher m = p.matcher(ssn);
if (m.find( )) {
    System.out.println(ssn + " is an invalid social security number");
}else{
    System.out.println(ssn + " is a valid social security number");
}
Dez
  • 5,702
  • 8
  • 42
  • 51
0

And if you hate regex as much as I do, you could also iterate through characters comparing to ASCII values.

public class HelloWorld{

 public static void main(String []args){
    System.out.println("Test A: " + checkSSN("123-45-6789"));
    System.out.println("Test B: " + checkSSN("12a-45-6789"));
    System.out.println("Test C: " + checkSSN("123-4"));
    System.out.println("Test D: " + checkSSN("123-45-20303"));
 }

 public static boolean checkSSN(String ssn) {
     int count = 0;
     for (char c : ssn.toCharArray()) {
         if (count == 3 || count == 6) {
             if (c != '-') {
                 System.out.println("Character" + c + "Not a dash, returning false");
                 return false;
             } 
         } else if (c < '0' || c > '9') {
             System.out.println("NaN, return false");
             return false;
         }
         count++;
     }
     if (count != 11) {
         System.out.println("Doesn't meet length criteria");
         return false;
     }
     return true;
 }

}

Ben Harris
  • 1,734
  • 3
  • 15
  • 24
  • Avoid [magic numbers](http://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad). Instead of 45 simply use `'-'`, instead of 48 you can write `'0'`, and `'9'` for 57. – Pshemo Oct 17 '16 at 23:17
  • This is true. Thanks! – Ben Harris Oct 17 '16 at 23:18
  • I don't see ASCII anywhere in here. `char` is a UTF-16 code unit. All of the expected characters are one UTF-16 code unit so comparison with literal `char` values as you have done is appropriate. – Tom Blodget Oct 17 '16 at 23:34