Java使用正则表达式在字符串中查找值
我想知道在java中使用matcher
的行为。Java使用正则表达式在字符串中查找值
我有一个模式,我编译和通过匹配器的结果运行时,我不明白为什么缺少一个特定的值。
我的代码:
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());
}
我被击中了“星战”,这是正确的,因为它是在我的模式。
但是我并没有将“星球大战”当成一击,我不明白为什么它是我的模式的一部分。
由于NFA正则表达式中的alternation是“渴望”,即第一个匹配获胜,而其余替代方法甚至没有经过测试,所以这种行为是预期的。此外,请注意,一旦正则表达式引擎在消费模式中发现匹配(并且您的消费模式不是零宽度断言,如前瞻/ lookbehind/word边界/锚点),则索引将提前到从该位置搜索比赛和下一场比赛。
因此,一旦您的第一个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);
}
顺便说一句,你的正则表达式中包含snatched (2017)
,和它不匹配(
和)
,它只匹配snatched 2017
。要匹配文字括号,必须转义(
和)
。我还为star wars
删除了一个隐藏条目。
这种方法是更好,但是我们还应该在'|'上分割字符串并完全匹配'str',以避免像AI这样的电影出现问题。 – steffen
@steffen:我用'\ |'分割,只是为了快速构建一个数组。我认为最好的方法是像往常一样定义它,用'String [] arr = {“term1”,“term2”,“etc。”};'。注意我甚至没有删除笨蛋,我想这些都是在设计时提供的。 –
我决定编辑答案以显示应该如何定义搜索项的数组。用'“\\ |”'分割是hacky。 –
要匹配整个输入序列,所以你应该使用Matcher.matches()
或添加^
和$
:
Pattern p = Pattern.compile("^(star war|Star War|Starwars|star wars|"
+ "star wars|pirates of the caribbean)$");
将打印
Regex : star wars
但我@NAMS同意:不要像这样构建你的正则表达式。
一种更好的方式来建立你的正则表达式将是这样的:
String pattern = "[Ss]tar[\\s]{0,1}[Ww]ar[s]{0,1}";
打破:
- [SS]:它会在第一位置 匹配或者S或S
- \ s:表示空间
-
{0,1}:
String pattern = "[Ss]tar[\\s]?[Ww]ar[s]?";
- :前一字符(或设置)将0至1倍
另一种方法是相匹配?:前一字符(或设置)将被一次或不匹配,在所有
有关详细信息,请参阅https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
编辑1:固定错字(\s
- >\\s
)。谢谢,@eugene。
交替组中匹配“胜利”的第一个替代方案,其余未被选中。一旦“星际战争”匹配,文本被消耗,就不会有更多的通行证。预计。你需要什么行为? –
有没有办法返回所有匹配? –
您将不得不单独检查每个模式,而不要将其作为长链改变。 – NAMS