Why is String.matches returning false in Java?

前端 未结 3 1129
太阳男子
太阳男子 2020-12-11 17:56
if(\"test%$@*)$(%\".matches(\"[^a-zA-Z\\\\.]\"))
    System.exit(0);

if(\"te/st.txt\".matches(\"[^a-zA-Z\\\\.]\"))
    System.exit(0);

The program

相关标签:
3条回答
  • 2020-12-11 18:38

    x.matches(y) is equivalent to

    Pattern.compile(y).matcher(x).matches()
    

    and requires the whole string x to match the regex y. If you just want to know if there is some substring of x that matches y then you need to use find() instead of matches():

    if(Pattern.compile("[^a-zA-Z.]").matcher("test%$@*)$(%").find())
        System.exit(0);
    

    Alternatively you could reverse the sense of the test:

    if(!"test%$@*)$(%".matches("[a-zA-Z.]*"))
    

    by providing a pattern that matches the strings that are allowed rather than the characters that aren't, and then seeing whether the test string fails to match this pattern.

    0 讨论(0)
  • 2020-12-11 18:46

    You obtain always false because the matches() method return true only when the pattern matches the full string.

    0 讨论(0)
  • 2020-12-11 18:56

    matches returns true only if regex matches entire string. In your case your regex represents only one character that is not a-z, A-Z or ..

    I suspect that you want to check if string contains one of these special characters which you described in regex. In that case surround your regex with .* to let regex match entire string. Oh, and you don't have to escape . inside character class [.].

    if ("test%$@*)$(%".matches(".*[^a-zA-Z.].*")) {
        //string contains character that is not in rage a-z, A-Z, or '.'
    

    BUT if you care about performance you can use Matcher#find() method which

    1. can return true the moment it will find substring containing match for regex. This way application will not need to check rest of the text, which saves us more time the longer remaining text is.

    2. Will not force us to constantly build Pattern object each time String#matches(regex) is called, because we can create Pattern once and reuse it with different data.

    Demo:

    Pattern p = Pattern.compile("[^a-zA-Z\\.]");
    
    Matcher m = p.matcher("test%$@*)$(%");
    if(m.find())
        System.exit(0);
    
    //OR with Matcher inlined since we don't really need that variable
    if (p.matcher("test%$@*)$(%").find())
        System.exit(0);
    
    0 讨论(0)
提交回复
热议问题