简体   繁体   中英

Regex test failing - Java

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 ie 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.

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;
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM