本人在学习java正则表达式,程序有个输出一直不能理解,希望大家能指点一下。程序代码如下:
public class RegexTestHarness {    public static void main(String[] args) throws IOException {
        String regex = null;
        boolean fixedRegex = regex != null;
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            if (!fixedRegex) {
                System.out.println("Enter your regex: ");
                regex = bufferedReader.readLine();
            }
            Pattern pattern
                    = Pattern.compile(regex);
            System.out.println("Enter input string to search: ");
            Matcher matcher
                    = pattern.matcher(bufferedReader.readLine());            boolean found = false;
            while (matcher.find()) {
                System.out.format("I found the text"
                        + " \"%s\" starting at "
                        + "index %d and ending at index %d.%n",
                        matcher.group(),
                        matcher.start(),
                        matcher.end());
                found = true;
            }
            if (!found) {
                System.out.println("No match found.");
            }
        }
    }
}输入输出如下:
Enter your regex: 
a??
Enter input string to search: 
a
I found the text "" starting at index 0 and ending at index 0.
I found the text "" starting at index 1 and ending at index 1.
Enter your regex: 我以为输出会是这样的:
I found the text "" starting at index 0 and ending at index 0.
I found the text "a" starting at index 0 and ending at index 1.
I found the text "" starting at index 1 and ending at index 1.一直想不明白,请大神指点一下。

解决方案 »

  1.   

    你这道题目涉及到的是JAVA对正则NFA和DFA的支持的问题.你可以百度了解下相关的一些说明.
      

  2.   

    你的正则表达式实际上是将NFA模式切换成DFA模式.如下面的代码.实际上是等价的.import java.util.regex.Matcher;
    import java.util.regex.Pattern;public class Test{
    public static void main(String[] args){
    String regex = "(|a?)";
    String content = "abc";
    Matcher matcher = Pattern.compile(regex).matcher(content);
    int start = 0;
    int end = 0;
    while(matcher.find()){
    start = matcher.start();
    end = matcher.end();
    System.out.println(String.format("'%s',start:%d,end:%d",matcher.group(),start,end));
    }
    System.out.println("---------------------------------------------------");
    regex = "a??";
    content = "abc";
    matcher = Pattern.compile(regex).matcher(content);
    start = 0;
    end = 0;
    while(matcher.find()){
    start = matcher.start();
    end = matcher.end();
    System.out.println(String.format("'%s',start:%d,end:%d",matcher.group(),start,end));
    }
    }
    }
      

  3.   

    Reluctant采用与Greedy相反的方法,它从输入串的首(字符)位置开始,在一次尝试匹配查找中只勉强地读一个字符,直到尝试完整个字符串。
    模式串:.*foo
    查找串:xfooxxxxxxfoo
    结果:matched form 0 to 4
          matched form 4 to 13
     
    其比较过程如下
     谢谢luoweifu的工作。详细请参考http://blog.csdn.net/luoweifu/article/details/42759439
      

  4.   


    谢谢。查了些正则NFA和DFA的资料,感觉内容有点深,得慢慢啃。你能再讲讲为什么“a??”匹配“a",匹配的是两个”“,而匹配不到”a"吗?
      

  5.   


    还是不能理解为什么“a??”匹配“a",匹配的是两个”“,而匹配不到”a"
      

  6.   


    谢谢。查了些正则NFA和DFA的资料,感觉内容有点深,得慢慢啃。你能再讲讲为什么“a??”匹配“a",匹配的是两个”“,而匹配不到”a"吗?
    你可以理解下下面的等价
    a? --> (a|)
    a?? -->(|a)
      

  7.   


    还是不能理解为什么“a??”匹配“a",匹配的是两个”“,而匹配不到”a"我开始时候误解你的问题了,不好意思,但是从写代码的思路来讲,最优先符合规则的,就应该判断为满足,然后结束循环。
    比如这个 a 既然可以一次也没有,那么为什么还要去匹配它有呢?再去匹配有a 的话,不是又要消耗资源吗?当没有a的时候也可以满足,那么就可以直接结束循环了。也就是说 一个或一个也没有,实际上是判断它不超过1个。
      

  8.   


    还是不能理解为什么“a??”匹配“a",匹配的是两个”“,而匹配不到”a"我开始时候误解你的问题了,不好意思,但是从写代码的思路来讲,最优先符合规则的,就应该判断为满足,然后结束循环。
    比如这个 a 既然可以一次也没有,那么为什么还要去匹配它有呢?再去匹配有a 的话,不是又要消耗资源吗?当没有a的时候也可以满足,那么就可以直接结束循环了。也就是说 一个或一个也没有,实际上是判断它不超过1个。
    我没有了解到内部的机制,这只是我的个人想法,如果你找到更好的答案也请@我一下。
      

  9.   


    还是不能理解为什么“a??”匹配“a",匹配的是两个”“,而匹配不到”a"我之前的关于a??的匹配说法不是正确的,造成的误解我非常抱歉。还请你原谅。