正则表达式Matcher疑问,求指点

kris_in_java 2010-09-17 10:21:10
写正则表达式的一个小例子遇到一个奇怪的问题。
在打印匹配的字符串的循环中调用了m.lookingAt()或m.matchs()居然出现死循环...如果不调用确不会出现这种情况。是这两个方法影响的么?查了api,看了源码,都不知道所以然,求高手指点下。在线等ing...

public class TestRegularExpression {

/**
* @param args
*/
public static void main(String[] args) {

String testString = "Never give up! Never surrender!";
String regularException = "Never.{8,10}!";

System.out.println(regularException);

Pattern p = Pattern.compile(regularException);
Matcher m = p.matcher(testString);
int i = 0;
while (m.find()) {
System.out.println("Match \"" + m.group() + "\" at positions "
+ m.start() + "-" + (m.end() - 1));
System.out.println(m.lookingAt());
System.out.println(m.matches());
}

}

}
...全文
145 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
kris_in_java 2010-09-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 eggno8 的回复:]
我也快晕了。
String testString = "Never give up! Never give up!Never give up!Never give up!";
String regularException = "Never give up!";//定长(固定的字符串非正则形式的)的可以正常走出,但如果Never.{8,10}!这种不定的将在第2论匹配那里循环。如果要深……
[/Quote]

一起在研究下吧,希望我们能找出答案
liu_yang_0923 2010-09-17
  • 打赏
  • 举报
回复
路过,看一下,学习一下
eggno8 2010-09-17
  • 打赏
  • 举报
回复
我也快晕了。
String testString = "Never give up! Never give up!Never give up!Never give up!";
String regularException = "Never give up!";//定长(固定的字符串非正则形式的)的可以正常走出,但如果Never.{8,10}!这种不定的将在第2论匹配那里循环。如果要深究,可能从这里入手吧。
上面我说的
又看了看,问题应该在“find一轮的最后1次成功匹配的last如果是在结尾”将陷入循环。
是个错误结论。
kris_in_java 2010-09-17
  • 打赏
  • 举报
回复
死了一试,还是有点晕

把正则表达式该为"Never.*?!"
循环中调一次matchs和调lookingAt又不一样
eggno8 2010-09-17
  • 打赏
  • 举报
回复
又看了看,问题应该在“find一轮的最后1次成功匹配的last如果是在结尾”将陷入循环。
String testString = "Never give up! Never surrender!Never shut up!";
String regularException = "Never";//never就可以顺利出来,"Never.{8,10}"出不来。
eggno8 2010-09-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 tassdars 的回复:]

楼主看一下API文档的说明,lookingAt()“尝试将从区域开头开始的输入序列与该模式匹配”,matches()是“尝试将整个区域与模式匹配”。

匹配正则的时候有个游标的,你调用find()方法找到了某个匹配,就会把游标移动到该匹配的位置,这个时候你又调用lookingAt()或者matches(),得了,又把游标移到开始位置了,然后又执行find()方法,又把游标移动到第一个匹配的位……
[/Quote]
开始我也像1楼这么想的,合情合理。但是实验了一下,原因应该不这么简单:

String testString = "Never give up! Never surrender!Never shut up!";//改成这样3次匹配将正常find()一圈后退出,如果是2个匹配的则陷入死循环
String regularException = "Never";

System.out.println(regularException);

Pattern p = Pattern.compile(regularException);
Matcher m = p.matcher(testString);
int i = 0;
while (true) {//这么改了改方便调试
i++;//bp1
if(m.find()){
System.out.println("Match \"" + m.group() + "\" at positions "
+ m.start() + "-" + (m.end() - 1));//bp2
System.out.println(m.matches());
if (i > 200) {//bp3
break;
}
}else{
break;
}
}

下了断点观察了matcher的first,last,oldlast等几个属性,原文字2次匹配和3次匹配有区别,但没总结出来原因,也许是观察还不够仔细。估计要等果子兄了。
kris_in_java 2010-09-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 tassdars 的回复:]
楼主看一下API文档的说明,lookingAt()“尝试将从区域开头开始的输入序列与该模式匹配”,matches()是“尝试将整个区域与模式匹配”。

匹配正则的时候有个游标的,你调用find()方法找到了某个匹配,就会把游标移动到该匹配的位置,这个时候你又调用lookingAt()或者matches(),得了,又把游标移到开始位置了,然后又执行find()方法,又把游标移动到第一个匹配的位置……
[/Quote]

谢谢,这个可能我想过,但是我还要问,如果像你说的lookingAt或matchs把游标移动到起始位置,那应该是死循环输出第一次匹配,但是输出结果却是:
Never.{8,10}!
Match "Never give up!" at positions 0-13
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false
Match "Never surrender!" at positions 15-30
false

朋友,还能帮我解释下吗?
Tassdars 2010-09-17
  • 打赏
  • 举报
回复
楼主看一下API文档的说明,lookingAt()“尝试将从区域开头开始的输入序列与该模式匹配”,matches()是“尝试将整个区域与模式匹配”。

匹配正则的时候有个游标的,你调用find()方法找到了某个匹配,就会把游标移动到该匹配的位置,这个时候你又调用lookingAt()或者matches(),得了,又把游标移到开始位置了,然后又执行find()方法,又把游标移动到第一个匹配的位置,又调用lookingAt()或者matches(),又把游标移到开始位置了,不是死循环才有鬼。

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧