Java使用正则表达式在字符串中查找值

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

我被击中了“星战”,这是正确的,因为它是在我的模式。

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

+3

交替组中匹配“胜利”的第一个替代方案,其余未被选中。一旦“星际战争”匹配,文本被消耗,就不会有更多的通行证。预计。你需要什么行为? –

+0

有没有办法返回所有匹配? –

+3

您将不得不单独检查每个模式,而不要将其作为长链改变。 – NAMS

由于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); 
} 

Java demo

顺便说一句,你的正则表达式中包含snatched (2017),和它不匹配(),它只匹配snatched 2017。要匹配文字括号,必须转义()。我还为star wars删除了一个隐藏条目。

+0

这种方法是更好,但是我们还应该在'|'上分割字符串并完全匹配'str',以避免像AI这样的电影出现问题。 – steffen

+0

@steffen:我用'\ |'分割,只是为了快速构建一个数组。我认为最好的方法是像往常一样定义它,用'String [] arr = {“term1”,“term2”,“etc。”};'。注意我甚至没有删除笨蛋,我想这些都是在设计时提供的。 –

+0

我决定编辑答案以显示应该如何定义搜索项的数组。用'“\\ |”'分割是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。

+0

''\\\\\\\\\\\\\\\\\\\\\\\\'''{\\\\\\\\\\\\\\\\''')可能会有很多空格,可能是 – Eugene

+0

尤金:*会导致匹配0次或更多次。通过使用{0,1}它只表示匹配0或1次。 – luizfzs

+0

@Eugene - '\'s *'将允许像'星球大战'这样的事物相匹配。 – marklark