java正则表达式保持处理,但不会抛出任何结果
所以我在学习java中的正则表达式,我想知道为什么我要执行这段代码
String xxx = "(\\s+)?(c:/|c:\\\\|C:\\\\|C:/|c:\\|C:\\))?(\\w+(/|\\\\)?)+(/|\\\\)\\w+.[a-z]+";
String x = "C:\\Users\\esteban\\Desktop\\Java_file_testing\\file3.txt";
if(x.matches(xxx)) {
System.out.println("matches");
}else {
System.out.println("no match found ");
}
这会打印出matches
,但是当我删除.txt
时,没有任何响应,我是不是做错了什么
# 1 楼答案
你偶然发现了一个catastrophic backtracking案例
在编写
(\\w+(/|\\\\)?)+
时,基本上是在正则表达式中引入(\\w+)+
模式。这使得正则表达式引擎有机会以多种方式(使用内部或外部+
)匹配同一个字符串——可能的路径数呈指数增长,而且由于引擎在声明失败之前必须尝试所有可能的匹配方式,因此返回值需要花费很长时间另外,对你的正则表达式有一些一般性的评论:
c:\\|
将匹配字符串c:|
/|\\\\
只是[/\\\\]
(\s+)?
是\s*
.
是一个需要转义的通配符(“除了换行以外的任何内容”)c
/C
变体,可以使用[cC]
或使整个正则表达式case insensitive(?:...)
可以减轻引擎的一些工作考虑到这些因素,符合你第一次尝试精神的正则表达式可能是:
在
(?:\\w+[/\\\\])
中,字符类[/\\\\]
不再是可选的,因此避免了(\\w+)+
模式:请参见demo here关于灾难性回溯的更多信息,我推荐优秀的(而且有趣!)弗里德尔关于the perl journal主题的文章