我想知道在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());
}
我受到“星球大战”的打击,因为它符合我的模式。
但是我没有把“星球大战”当作一个打击,我不明白为什么它是我模式的一部分。
答案 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}";
分解:
另一种选择是:
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:不要像这样构建你的正则表达式。