Home > Enterprise >  How to determine how many characters are in a string and if the characters are digits or not Java
How to determine how many characters are in a string and if the characters are digits or not Java

Time:12-15

I am doing a customer information scanner project for school, currently I am working on the phone number portion. I need to have the customer enter their phone number and I need to detect as many errors as possible. This includes: make sure it's all digits, make sure its ten digits, then to divide into - <3 digit String for Area Code> <3 digit String for Central Office > <4 digit String for Station Code> and finally add dashes between the area code, central office, and station code. Are there any easy ways to do this, here is my current code. Thanks in advance

System.out.println(DATA_DIV);
System.out.println("\nCustomer Phone Number Information");
System.out.println("-----------------------------------\n");
System.out.println("Enter the Phone Number:");

phoneNumber = uIn.next();
    
if (phoneNumber.matches("\\d ")) {

} 
else {
    Garbage = uIn.next();
    System.out.println("\n\tError Data Type: you entered ( "   Garbage   " ) for Phone Number");
    System.out.println("Phone Number must be made up of numbers only");
    System.out.println();
    System.out.println("Re-Enter the Phone Number :");
    phoneNumber = uIn.next();
}

CodePudding user response:

I would suggest you get familiar with regular expressions as they come really handy in situations like this one. The regex I would suggest you use: ^(?\d{3})(?\d{3})(?\d{4})$

^ - means start of the sequence

(?<area/office/code>) - that’s how we basically create a group and give it a name so we can call it by it later when we need it.

\d - digit

{3} - the exact number of the preceding element we’re looking for

$ - end of sequence

After that you should use the Pattern and Matcher classes in order to get the right sequences, there are handy methods like find(groupName) in the Matcher class. I think splitting is quite straightforward after this.

CodePudding user response:

Personally, I don't like using regex to solve this kind of problem. The alternative to using regex as mentioned in the comments is to build a scanner and parser from a Backus-Naur description for a phone number. The description appears below:

<phone number> ::= <area code>-<central office>-<station code>
<area code> ::= <digit><digit><digit>
<central office> ::= <digit><digit><digit>
<station code> ::= <digit><digit><digit><digit>
<digit> ::= 0|1|2|3|4|5|6|7|8|9

The scanner and parser is as follows:

import java.util.Scanner;

public class PhoneNumberParser {
    PhoneNumber number;
    int look;               // Current char read
    int index;              // Index into input buffer
    String input;           // Raw phone number input

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        PhoneNumberParser parser = new PhoneNumberParser();
        try {
            PhoneNumber number = parser.parse(scanner.nextLine());
            System.out.println(number);
        }catch(IllegalArgumentException ex) {
            System.err.println(ex);
        }
    }

    public PhoneNumber parse(String s) throws IllegalArgumentException{
        number = new PhoneNumber();
        input = s;
        index = 0;

        //if( s.length() != 10 )
        //    throw new IllegalArgumentException("Bad phone number. Expected a ten digit number.");

        scan();

        number.areaCode = areaCode();
        scan();
        if( look != '-')
            throw new IllegalArgumentException("Bad phone number. Expected a '-' after the area code.");
        scan();
        number.centralOffice = centralOffice();
        scan();
        if( look != '-')
            throw new IllegalArgumentException("Bad phone number. Expected a '-' after the central office part.");
        scan();
        number.stationCode = stationCode();
        return number;
    }

    private void scan() {
        try {
            look = input.charAt(index  );
        }catch(Exception ex) {
            look = -1;
        }
    }

    private int areaCode() {
        StringBuffer sb = new StringBuffer();
        sb.append(digit());
        scan();
        sb.append(digit());
        scan();
        sb.append(digit());
        return Integer.parseInt(sb.toString());
    }

    private int centralOffice() {
        StringBuffer sb = new StringBuffer();
        sb.append(digit());
        scan();
        sb.append(digit());
        scan();
        sb.append(digit());
        return Integer.parseInt(sb.toString());
    }
    private int stationCode() {
        StringBuffer sb = new StringBuffer();
        sb.append(digit());
        scan();
        sb.append(digit());
        scan();
        sb.append(digit());
        scan();
        sb.append(digit());
        return Integer.parseInt(sb.toString());
    }
    private int digit() {
        if( ! Character.isDigit((char) look) )
            throw new IllegalArgumentException("Bad phone number. Expected a digit, but found a '"   (char)look   "' character.");
        int digit = (char)look - '0';
        return digit;
    }



    class PhoneNumber {
        int areaCode;
        int centralOffice;
        int stationCode;
        public String toString() {
            return "Area code: "   areaCode   " Central office: "   centralOffice   " Station code: "   stationCode;
        }
    }
}

Output when supplied with the string 999-888-1234 is:

Area code: 999 Central office: 888 Station code: 1234

As you can see, the scanner parser gives better error reporting for bad numbers than regexp and also separates out the number into its constituent parts for further processing. For example, it may be important to just display the area code portion of the number.

  • Related