Java匹配模式问题

时间:2016-09-21 16:05:13

标签: java pattern-matching matcher

我正在尝试提取此字符串路径/share/attachments/docs/之后的所有内容。我的所有字符串都以/share/attachments/docs/

开头

例如:/share/attachments/docs/image2.png ../docs/之后的字符数不是静态的!

我试过

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

但我得到的异常是:No match found. 奇怪,因为如果我使用它:

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

然后它有效!!!

还有一件事是,在一些非常罕见的情况下,我的字符串不会以/share/attachments/docs/开头,然后我不应解析任何东西,但这与问题没有直接关系,但处理起来会很好。< / p>

2 个答案:

答案 0 :(得分:3)

  

我得到的异常是:No match found.

这是因为image2.png\d+不匹配使用更合适的模式,例如.+,假设您要提取image2.png

您的正则表达式将为^(.*)/share/attachments/docs/(.+)$

如果是ABC Results for draw no 2888,则正则表达式^(.*)ABC Results for draw no (\\d+)$有效,因为您在String末尾有几个连续的数字,而在第一个案例中,您有image2.png字母和数字的混合,这就是找不到匹配的原因。

一般来说,为了避免获得IllegalStateException: No match found,您需要先检查find()的结果,如果它返回true输入String匹配:

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

答案 1 :(得分:1)

正则表达式\d+(在字符串文字中表示为\\d+)匹配一个或多个数字的运行。您的示例输入没有相应的数字运行,因此不匹配。正则表达式元字符.匹配任何字符(+/-换行符,具体取决于正则表达式选项);看起来这可能是你真正想要的。

此外,当您使用Matcher.find()时,模式不必匹配整个字符串,因此不必包含.*来匹配前导上下文。此外,find() 返回一个值,告诉您是否找到了与模式的匹配项。您通常希望使用此返回值,在特定情况下,您可以使用它来拒绝那些罕见的不匹配字符串。

也许这更像是你想要的:

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