简体   繁体   中英

Java Matcher Pattern issue

I am trying to extract everything that is after this string path /share/attachments/docs/ . All my strings are starting with /share/attachments/docs/

For example: /share/attachments/docs/image2.png Number of characters after ../docs/ is not static!

I tried with

   Pattern p = Pattern.compile("^(.*)/share/attachments/docs/(\\d+)$");
   Matcher m = p.matcher("/share/attachments/docs/image2.png");
   m.find();         
   String link = m.group(2);    
   System.out.println("Link #: "+link);

But I am getting Exception that: No match found. Strange because if I use this:

   Pattern p = Pattern.compile("^(.*)ABC Results for draw no (\\d+)$");
   Matcher m = p.matcher("ABC Results for draw no 2888");

then it works!!!

Also one thing is that in some very rare cases my string does not start with /share/attachments/docs/ and then I should not parse anything but that is not related directly to the issue, but it will be good to handle.

I am getting Exception that: No match found.

This is because image2.png doesn't match with \\d+ use a more appropriate pattern like .+ assuming that you want to extract image2.png .

Your regular expression will then be ^(.*)/share/attachments/docs/(.+)$


In case of ABC Results for draw no 2888 , the regexp ^(.*)ABC Results for draw no (\\\\d+)$ works because you have several successive digits at the end of your String while in the first case you had image2.png that is a mix of letters and digits which is the reason why there were no match found.


Generally speaking to avoid getting an IllegalStateException: No match found , you need first to check the result of find() , if it returns true the input String matches:

if (m.find()) {
   // The String matches with the pattern
   String link = m.group(2);    
   System.out.println("Draw #: "+link);
}  else {
   System.out.println("Input value doesn't match with the pattern");
}

The regular expression \\d+ (expressed as \\\\d+ inside a string literal) matches a run of one or more digits . Your example input does not have a corresponding digit run, so it is not matched. The regex metacharacter . matches any character (+/- newline, depending on regex options); it seems like that may be what you're really after.

Additionally, when you use Matcher.find() it is unnecessary for the pattern to match the whole string, so it is needless to include .* to match leading context. Furthermore, find() returns a value that tells you whether a match to the pattern was found. You generally want to use this return value, and in your particular case you can use it to reject those rare non-matching strings.

Maybe this is more what you want:

Pattern p = Pattern.compile("/share/attachments/docs/(.+)$");
Matcher m = p.matcher("/share/attachments/docs/image2.png");
String link;

if (m.find()) {
    link = m.group(1);
    System.out.println("Draw #: " + link);
} else {
    link = null;
    System.out.println("Draw #: (not found)");
}

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