Java Regex中的零长度匹配

我的代码:

Pattern pattern = Pattern.compile("a?"); Matcher matcher = pattern.matcher("ababa"); while(matcher.find()){ System.out.println(matcher.start()+"["+matcher.group()+"]"+matcher.end()); } 

输出:

 0[a]1 1[]1 2[a]3 3[]3 4[a]5 5[]5 

我知道的 :

  • “一个?” 代表字符’a’的零或一次出现。

Java API说:

  • matcher.start()返回上一个匹配的起始索引。
  • matcher.end()返回最后一个字符匹配后的偏移量。
  • matcher.group()返回上一个匹配项匹配的输入子序列。 对于具有输入序列s的匹配器m,表达式m.group()和s.substring(m.start(),m.end())是等价的。 对于某些模式,例如a *,匹配空字符串。 当模式成功匹配输入中的空字符串时,此方法将返回空字符串。

我想知道的是什么:

  1. 在哪种情况下,正则表达式引擎遇到给定字符的零次出现 – 这里是字符’a’。
  2. 在这种情况下,匹配器中的start(),end()和group()方法实际返回的值是什么。 我已经提到过java API所说的内容。 但就上述实际情况而言,我不太清楚。

? 是一个贪婪的量词,因此它会在尝试0次出现之前首先尝试匹配1次出现。 在你的字符串中,

  1. 它从第一个字符’a’开始,并尝试再次匹配1次出现。 ‘a’字符匹配,因此它返回您看到的第一个结果
  2. 然后它向前移动并找到’b’。 ‘b’字符与正则表达式1出现不匹配,因此引擎回溯并尝试匹配0出现。 结果是匹配空字符串 – >得到第二个结果。
  3. 然后它移动到b之前,因为那里不再有匹配,并且它再次以你的第二个’a’字符开始。
  4. 等……你明白了……

它比这复杂一点,但这是主要的想法。 当1次出现不匹配时,它将尝试0次出现。

至于start,end和group的值,它们将是匹配开始,结束和组匹配的位置,所以在你的字符串的第一个0-occurence匹配中,你得到1,1和emtpy字符串。 我不确定这真的能回答你的问题。

迭代几个例子可以清除matcher.find()给你的function:

正则表达式引擎从字符串(即ababa)中获取一个字符,并尝试查找是否可以找到您在字符串中搜索的模式。 如果模式存在,那么(如提到的API):

matcher.start()返回起始索引,matcher.end()返回最后一个字符匹配后的偏移量。

如果匹配不存在。 然后start()和end()返回相同的索引,这符合匹配的长度为零。

请查看以下示例:

  // Searching for string either "a" or "" Pattern pattern = Pattern.compile("a?"); Matcher matcher = pattern.matcher("abaabbbb"); while(matcher.find()){ System.out.println(matcher.start()+"["+matcher.group()+"]"+matcher.end()); } 

输出:

  0[a]1 1[]1 2[a]3 3[a]4 4[]4 5[]5 6[]6 7[]7 8[]8 // Searching for string either "aa" or "a" Pattern pattern = Pattern.compile("aa?"); Matcher matcher = pattern.matcher("abaabbbb"); while(matcher.find()){ System.out.println(matcher.start()+"["+matcher.group()+"]"+matcher.end()); } 

输出:

 0[a]1 2[aa]4