模式匹配中的不情愿限定符



我有以下程序

public class PatternMatching {
            public static void main(String[] args) {
                String pattern ="a??";
                Pattern pattern1 = Pattern.compile(pattern);
                String findAgainst = "a";
                Matcher matcher = pattern1.matcher(findAgainst);
                int count=0;
                while(matcher.find()){
                    count++;
                    System.out.println(matcher.group(0)+".start="+ matcher.start()+".end="+matcher.end());
                }
                System.out.println(count);
            }
        }

打印以下输出

.start=0.end=0
.start=1.end=1
2

而不是

.start=0.end=0
a.start=0.end=1
.start=1.end=1
3

当我运行模式为"b??"的程序时输出是

.start=0.end=0
.start=1.end=1
2

这是正确的。如果是一个不情愿的限定词,那么错误输出事件的原因是什么?

据我所见,问题是Java正则表达式引擎在遇到零长度匹配时使用以下算法:它将匹配的索引与当前正则表达式索引进行比较,如果它们一致,则正则表达式索引将递增。

因此,当您将a之前的空格与a??匹配时,正则表达式引擎发现长度为零的匹配,并增加出现在a之后的索引,从而跳过正确的匹配。

如果您使用贪婪版本a?,则输出将不同:

a.start=0.end=1
.start=1.end=1
2

发生这种情况是因为第一个a已被使用,regex引擎索引在a之后,现在可以匹配字符串的末尾。

最新更新