为什么Matcher.find()在Matcher.lookingAt()之后运行时返回false?

时间:2012-09-27 15:44:50

标签: java regex

我注意到调用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()的原因吗?

2 个答案:

答案 0 :(得分:4)

.lookingAt()的调用与匹配并消费 T234,因此以下.find()来电始于bird - 不匹配。

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

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

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

答案 1 :(得分:3)

在试用版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总是开始查看字符串的开头,而不是在上一个匹配的结尾,所以{{1只是永远循环。