4

我注意到调用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()

4

2 回答 2

4

.lookingAt()match和 consumes T234的调用,因此以下.find()调用从bird- 不匹配开始。

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

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

Matcher matches = Pattern.compile("^T\\d+").matcher("T234bird");
if (matches.find())
    System.out.println(matches.group());
于 2012-09-27T15:49:25.813 回答
3

在试验 1 中,呼叫lookingAt匹配T234,并且您随后的呼叫开始在前一场比赛结束find时寻找匹配。如果你想回到你需要调用的字符串的开头。Matcher.find()的文档中对此进行了解释:Matcher.reset()

此方法从该匹配器区域的开头开始,或者,如果该方法的先前调用成功并且匹配器此后尚未重置,则从前一个匹配不匹配的第一个字符开始。

请注意,它lookingAt适用于start, end,并且group方法相同find,因此如果您只对字符串的开头感兴趣,则可以这样做:

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

你必须使用if而不是在while这里,因为lookingAt总是从字符串的开头开始,而不是在上一个匹配的结尾,所以while永远循环。

于 2012-09-27T15:51:33.483 回答