Java Regex中的零长度匹配

时间:2012-03-28 11:23:43

标签: 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说。但在实际问题上我还不清楚 情况如上。

2 个答案:

答案 0 :(得分:11)

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

  1. 首先是第一个字母' a'并尝试再次匹配1次出现。 ' a' char匹配,因此它返回您看到的第一个结果
  2. 然后它向前移动并找到一个' b'。 ' b' char与正则表达式1出现不匹配,因此引擎回溯并尝试匹配0出现。结果是空字符串匹配 - >你得到了第二个结果。
  3. 然后它在b之前移动,因为那里不再有匹配,并且它会再次与你的第二个' a'炭。
  4. 等......你明白了......
  5. 它比这复杂一点,但这是主要的想法。当1次出现不匹配时,它将尝试0次出现。

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

答案 1 :(得分:3)

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

正则表达式引擎从字符串(即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