【问题标题】:Why does Matcher.find() return false when run after Matcher.lookingAt()?为什么 Matcher.find() 在 Matcher.lookingAt() 之后运行时返回 false?
【发布时间】:2012-09-27 23:58:24
【问题描述】:

我注意到调用Matcher.lookingAt() 会影响Matcher.find()。我在我的代码中运行了lookingAt(),它返回true。当我运行find() 以便开始返回匹配项时,我得到了false。如果我删除 lookingAt() 调用,find() 返回 true 并打印我的匹配项。有谁知道为什么?

试用1:

Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
System.out.println(matches.lookingAt()); //after running this, find() will return false
while (matches.find())
    System.out.println(matches.group());
//Output: true

试用2:

Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
//System.out.println(matches.lookingAt()); //without this, find() will return true
while (matches.find())
    System.out.println(matches.group());
//Output: T234

试用3:

Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
while (matches.lookingAt()) 
    System.out.println(matches.group());
//Output: T234 T234 T234 T234 ... till crash
//I understand why this happens. It's not my question but I just included it in case someone may try to suggest it

最终,我想要实现的是:首先确认匹配在字符串的开头,然后打印。我最终做了:

Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
if(matches.lookingAt()) 
    System.out.println(matches.group());
//Output: T234

这解决了我的问题,但我的问题是:有谁知道为什么lookingAt() 会影响find()

【问题讨论】:

    标签: java regex


    【解决方案1】:

    在试验 1 中,调用 lookingAtT234 匹配,您随后对 find 的调用开始在上一场匹配结束处寻找匹配。如果你想回到字符串的开头,你需要调用Matcher.reset()Matcher.find() 的文档中对此进行了解释:

    此方法在此匹配器区域的开头开始,或者,如果 该方法的先前调用成功并且匹配器具有 没有被重置,在第一个不匹配的字符处 上一场比赛。

    请注意,lookingAtstartendgroup 的使用方式与 find 相同,因此如果您只对字符串的开头感兴趣,则可以这样做:

    Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
    if (matches.lookingAt())
        System.out.println(matches.group());
    

    您必须在此处使用if 而不是while,因为lookingAt 总是从字符串的开头开始查找,而不是在上一个匹配项的结尾处,因此while 只会永远循环。

    【讨论】:

      【解决方案2】:

      .lookingAt() 的调用匹配并消耗T234,因此以下.find() 调用从bird 开始 - 不匹配。

      您需要重置匹配器对象才能重新开始。

      或者只是在你的正则表达式中使用字符串开头的锚点并立即使用.find()

      Matcher matches = Pattern.compile("^T\\d+").matcher("T234bird");
      if (matches.find())
          System.out.println(matches.group());
      

      【讨论】:

      • +1 好的,所以在lookingAt 找到匹配项后,它会在bird 继续。我懂了。 ^ 也是一个好主意。谢谢。
      • +1。现在帮自己一个忙,忘记你听说过lookingAt() 方法。它仅在极少数情况下有用,并且从不必要。
      猜你喜欢
      • 1970-01-01
      • 2021-07-23
      • 2011-11-30
      • 1970-01-01
      • 2013-09-18
      • 2011-05-22
      • 2014-11-17
      • 2014-03-11
      • 2019-07-12
      相关资源
      最近更新 更多