为什么模式不匹配“/ *!”?

时间:2013-05-12 03:00:44

标签: java regex

我正在尝试匹配某些东西而且为了我的生活,我无法弄清楚为什么它不能按预期工作。

字符串:"/*! preserved */"

模式:

Pattern.compile("(/[*][!](?:.+?)[*]/)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE)  
- FAIL

模式:

Pattern.compile("(/[*](?:.+?)[*]/)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE) 
- PASS

我只想在开始的评论字符串后面找到!的评论。我甚至尝试将匹配减少到/*!

Pattern.compile("(/[*][!])", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE) 
- FAIL

Pattern.compile("(/[*!]{2})", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE)
- FAIL

Pattern.compile("(/[*][!])", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE)
- FAIL


Java Version "1.6.0_43"
Java(TM) SE Runtime Environment (build 1.6.0_43-b01)
Java HotSpot(TM) 64-Bit Server VM (build 20.14-b01, mixed mode)

修改

这失败了,这对我来说没有意义,因为我的模式没有开始或结束的要求:

Pattern p = Pattern.compile("(/[*]!.+?[*]/)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("this is a test /*! preserved */ this is a test /*! preserved1 */");
System.out.println("Pattern: " + p);
System.out.println("Group: " + m.group(1));
System.out.println("Found: " + m.find());

即使将其缩减为仅匹配/*!也会失败:

Pattern p = Pattern.compile("(/[*]!)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("this is a test /*! preserved */ this is a test /*! preserved1 */");
System.out.println("Match: " + m.find());
System.out.println("Pattern: " + p);
System.out.println("Group: " + m.group(1));

3 个答案:

答案 0 :(得分:3)

    Pattern p = Pattern.compile("(/[*]!.+?[*]/)", Pattern.MULTILINE | Pattern.DOTALL
            | Pattern.CASE_INSENSITIVE);
    System.out.println(p.matcher("/*! preserved */").matches());

输出

true

答案 1 :(得分:2)

取自matcher.find()的javadoc。

public boolean find()
     

尝试查找与模式匹配的输入序列的下一个子序列。此方法从此匹配器区域的开头开始,或者,如果方法的先前调用成功且匹配器尚未重置,则在第一个与上一个匹配项不匹配的字符处开始。

     

如果匹配成功,则可以通过startendgroup方法获取更多信息。

     

<强>返回:

     

true当且仅当输入序列的子序列与此匹配器的模式匹配时

查找从最后一场比赛结束开始搜索。不是从字符串的开头。这是m.find()返回false的原因。

您可以通过此示例看到此行为。

Pattern p = Pattern.compile(".*(/[*]!.+?[*]/).*", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("this is a test /*! preserved */ this is a test /*! preserved1 */");
//System.out.println("Match: " + m.matches());
//System.out.println("Pattern: " + p);
//System.out.println("Group: " + m.group(1));
System.out.println("Found: " + m.find());

返回true。但是,如果您取消注释其他行,m.find()将返回false。

如果在调用m.reset()之前调用m.find(),您将能够判断该模式是否在字符串中的任何位置。然而,这会重置匹配器的状态,这可能是不可取的。

修改

要使用find查找所有匹配项,请使用以下代码。 (注意缺少的.*

Pattern p = Pattern.compile("(/[*]!.+?[*]/)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("this is a test /*! preserved */ this is a test /*! preserved1 */");
while(m.find()) {
    System.out.println(m.group());
}

输出

/*! preserved */
/*! preserved1 */

由于Matcher.matches()必须与整个字符串匹配,因此需要稍微复杂的正则表达式来查找可能不合适的所有匹配项。

答案 2 :(得分:-2)

基于String API的示例,用于验证密码。

    String password = "Velu1!";
    String pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*+=_-])(?=\\S+$).{6,100}$";
    if (!password.matches(pattern)) {
        System.out.println("Invalid Password!");
    } else {
        System.out.println("Valid Password!");
    }

在这种情况下,您的模式是

  String pattern = "(/[*]!.+?[*]/)";