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

时间:2016-05-13 09:08:57

标签: java regex

我有以下程序

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

这是正确的。输出错误的原因是什么,尽管它是一个不情愿的限定符?

1 个答案:

答案 0 :(得分:1)

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

因此,当您将a之前的空格与a??匹配时,正则表达式引擎会找到零长度匹配并增加 {{1}之后出现的索引因此,跳过正确的匹配。

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

a?

这是因为第一个a.start=0.end=1 .start=1.end=1 2 被消耗,正则表达式引擎索引在a之后,现在可以匹配字符串结尾。