6

I'm attempting a simple regex execution. Essentially I want to determine if I've got special characters in my string and if so check each character of the string for two specific characters i.e. hypen and dot.

I seem to be having a problem in the first bit which involves determining if I've got special characters in my string.

Below is my method which I attempt to do this followed by the strings I'm having issues with:

public static boolean stringValidity(String input) {
    int specials = 0;

    Pattern p = Pattern.compile("[^a-zA-Z0-9 ]");
    Matcher m = p.matcher(input);
    boolean b = m.find();

    if (b) {
        System.out.println("\nstringValidity - There is a special character in my string");

        for (int i = 0; i < input.length(); ++i) {

           char ch = input.charAt(i);

           //if (!Character.isDigit(ch) && !Character.isLetter(ch) && !Character.isSpace(ch)) {
              ++specials;

              System.out.println("\nstringValidity - Latest number of special characters is: " + specials);

              if((ch == '-') | (ch == '.')) {
                  specialCharValidity = true;

                  System.out.println("\nstringValidity - CHAR is valid - specialCharValidity is: " + specialCharValidity + " as char is: " + ch);
              } else {
                  specialCharValidity = false;

                  System.out.println("\nstringValidity - CHAR is invalid - specialCharValidity is: " + specialCharValidity + " as char is: " + ch);

                  break;
              }
           //}
        }
    } else {
        System.out.println("\nstringValidity - There is NO special character in my string");

        specialCharValidity = true;
    }

    return specialCharValidity;
}

Below are strings I passed to the method which I expected to be considered as strings with special characters but the test failed:

"QWERTY"!£$"£$"
"sdfGSDFGSDFG%*^(%*&("

Below are strings I passed to the method which I expected NOT to be considered as strings with special characters but the test failed:

"QWE12342134RTY"
"LOREMIPSUM2354214"

Any suggestions are appreciated.

3
  • Works for me ... Pattern.compile("[^a-zA-Z0-9 ]").matcher("sdfGSDFGSDFG%^(%&(").find() returns true. Pattern.compile("[^a-zA-Z0-9 ]").matcher("QWE12342134RTY").find() returns false Commented Dec 15, 2014 at 17:14
  • The function kind of works if you uncomment the commented out lines. Commented Dec 15, 2014 at 17:48
  • @Dima and Salaman: After uncommenting the if statemnt and changing the pattern to [^a-zA-Z0-9 \\-\\.] it worked. Thanks for the suggestions Commented Dec 16, 2014 at 11:16

2 Answers 2

1

You can simplify your code by checking the string against the following pattern:

[^a-zA-Z0-9 \-\.]

The string validity function boils down to:

public static boolean stringValidity(String input) 
{
    return Pattern.compile("[^a-zA-Z0-9 \\-\\.]").matcher(input).find() == false;
}
Sign up to request clarification or add additional context in comments.

Comments

0

Running your code with the supplied strings gave me the following output:

stringValidity - There is a special character in my string

stringValidity - Latest number of special characters is: 1

stringValidity - CHAR is invalid - specialCharValidity is: false as char is: Q
---

stringValidity - There is a special character in my string

stringValidity - Latest number of special characters is: 1

stringValidity - CHAR is invalid - specialCharValidity is: false as char is: s
---

stringValidity - There is NO special character in my string
---

stringValidity - There is NO special character in my string
---

I guess this means there is nothing wrong with the pattern you are using to find special chars (not digits nor letters). But I've found the following issues with your code:

  1. Make sure you are properly passing those strings as parameters. The first string in your list should be declared like this "QWERTY\"!£$\"£$" in your program once java requires double quotes inside strings to be preceded by a back slash in order not to be interpreted as string delimiters;
  2. The second part of your test is not working because you are only testing the first char in your string. Your logic is saying something like "if the current char is a dot or an hyphen, specialCharValidity = true, otherwise (in case it is any other invalid OR valid char other than a dot and an hyphen) just make specialCharValidity = false and break the loop". Oddly, you have already done the right thing: just re-enable the lines you've commented to list the proper invalid char. If you want to enable the counting of specials you just need to remove line with break so the loop wont stop in the first special;

A few suggestions

  • Replace Character.isSpace() with Character.isWhitespace() as the first version is deprecated already;
  • Define specialCharValidity locally to avoid potential problems;
  • For the sake of performance, do not compile the same pattern on every call like you are doing on the line Pattern p = Pattern.compile("[^a-zA-Z0-9 ]");. Compiling a pattern is time consuming so you can just define a constant on top of your class like static public final Pattern p = Pattern.compile("[^a-zA-Z0-9 ]"); and use it later;
  • Patterns are an excellent tool to match complex string patterns but are a little overkill in this case. If you just need to match/find chars like this you'd better go for char comparison alone as patterns would just add unnecessary overhead.

1 Comment

Thanks for the response. I've attempted my code once more but with [^a-zA-Z0-9 \\-\\.] as the pattern as opposed to [^a-zA-Z0-9 ]. Essentially based on ulix's reply uncommenting the checks I had placed i.e. isDigit(), isLetter() and isWhiteSpace() enable me to test PAST the 1st character. I tested this with the strings I mentioned in my original post. Also I really appreciate your extra suggestions which I have implemented and have me clean up the code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.