Java使用正则表达式

时间:2017-05-26 18:36:28

标签: java regex java-8

我想知道在java中使用matcher的行为。

我有一个我编译的模式,当运行匹配器的结果时,我不明白为什么缺少特定的值。

我的代码:

String str = "star wars";
Pattern p = Pattern.compile("star war|Star War|Starwars|star wars|star wars|pirates of the caribbean|long strage trip|drone|snatched (2017)");
Matcher matcher = p.matcher(str);
while (matcher.find()) {
        System.out.println("\nRegex : " matcher.group());
    }

我受到“星球大战”的打击,因为它符合我的模式。

但是我没有把“星球大战”当作一个打击,我不明白为什么它是我模式的一部分。

3 个答案:

答案 0 :(得分:2)

这种行为是预期的,因为NFA正则表达式中的alternation是"渴望",即第一场比赛获胜,其余的备选项甚至没有经过测试。另外,请注意,一旦正则表达式引擎在消费模式中找到匹配(并且您的消费模式是消费模式,它不是零宽度断言,如前瞻/后瞻/单词边界/锚),索引将提前到结尾从该位置搜索匹配和下一个匹配。

因此,一旦您的第一个star war替代分支匹配,就无法匹配star wars,因为正则表达式索引位于最后一个s之前。

只需检查字符串是否包含您检查的字符串,最简单的方法是使用循环:

String str = "star wars";
String[] arr = {"star war","Star War","Starwars","star wars","pirates of the caribbean","long strage trip","drone","snatched (2017)"};
for(String s: arr){
    if(str.contains(s))
        System.out.println(s);
}

请参阅Java demo

顺便说一下,你的正则表达式包含snatched (2017),它与()不匹配,只与snatched 2017匹配。要匹配字面括号,必须转义()。我还删除了star wars的重复条目。

答案 1 :(得分:1)

构建正则表达式的更好方法是:

String pattern = "[Ss]tar[\\s]{0,1}[Ww]ar[s]{0,1}";

分解:

  • [Ss] :它会匹配第一个位置的S或s
  • \ s :空间表示
  • {0,1} :上一个字符(或集)将匹配0到1次

另一种选择是:

String pattern = "[Ss]tar[\\s]?[Ww]ar[s]?";
  • :上一个字符(或字符集)将匹配一次或根本不匹配

有关详细信息,请参阅https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

修改1:修正拼写错误(\s - > \\s)。谢谢,@ eugene。

答案 2 :(得分:0)

您希望匹配整个输入序列,因此您应该使用Matcher.matches()或添加^$

Pattern p = Pattern.compile("^(star war|Star War|Starwars|star wars|"
        + "star wars|pirates of the caribbean)$");

将打印

Regex : star wars

但我同意@NAMS:不要像这样构建你的正则表达式。