简体   繁体   中英

Regex quantifiers not working as expected

I can't seem to figure out regular expression quantifiers. Something as simple as look for "..." does not work for me.

This is my pattern:

Pattern p = Pattern.compile("\\.{3}");

Am I understanding something wrong? The expression "X{n}" means, take X exactly n times?

But Strings like "...." work just fine, even though it isn't exactly 3 times.

I assume that since ... returns also true for .... then you are using find method from Matcher class. Now I can see at least two things you want to achieve:

  1. you want to check if entire string is only ...
  2. you want to check if string contains ... but only if it is exactly 3 dots, so you don't want to accept ... if it has some additional dot before or after it.

To solve case one you simply need to use matches method like

Pattern p = Pattern.compile("\\.{3}");
Matcher m = p.matcher("...");
System.out.println(m.matches());//returns true
m = p.matcher("....");
System.out.println(m.matches());//returns false

To solve second case you will need to use negative-look-around mechanism to explicitly say that there shouldn't be any dots before or after ... so your regex can look like

Pattern p = Pattern.compile("(?<!\\.)\\.{3}(?!\\.)");

and now you can just use find method like you probably earlier did.

Matcher m = p.matcher("some... words. with dots.. after..... them...");
while(m.find())
    System.out.println(m.group()+" found at position "+m.start());

which will print

... found at position 4
... found at position 42

This depends the method you use, if you use the find method or lookingAt , since there is \\\\.{3} inside .... you will obtain a match, because the three dots are found.

To match exactly a pattern from the begining to the end of the string, you need the method matches

Or you can use anchors for start ^ and end $ of the string:

with lookingAt: \\.{3}$
with find:      ^\\.{3}$

Anchors are not needed with matches .

If you need to find exactly ... inside a larger string with the find method, you need to use a lookbehind and a lookahead assertion to ensure there is no dot after and before:

(?<!\\.)\\.{3}(?!\\.)    # not preceded by a dot, not followed by a dot

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