下面是一段标准的JAVA源代码
/**
 * 1,test
 */
public class Test {
    public void test() {
        System.out.println("2,//test 3,/* test */");  //4, test
    }
}很明显,
1,test和4, test和标准的注释,
2,//test 3,/* test */则是 引用字符串怎么用正则表达式判断1,2,3,4中的test,
当是注释时,将它替换成  xxxx
引用时,替换成yyyy

解决方案 »

  1.   

    研究一下Eclipse,或者其他编辑器源码.
      

  2.   

    这种问题我们应该仿照java编译器的做法,正则表达式不是明智的选择。楼主的要求就是找出字符串中的那些注释符号。编译器处理这些问题一般是使用栈来找出成对出现的字符或者字符串。
    也就是说我们碰到"先入栈,后面碰到非"的字符(包括转义字符\")我们都可以认为是字符串里面的内容,直到一个碰到应该成对出现的",就把之前栈内的"弹出。
    所以当我们碰到注释字符的时候,先查看栈内是否有围匹配的",有则说明是字符串内,不予考虑。否则,则认为这是注释。
      

  3.   

    >使用栈来找出成对出现的字符或者字符串这种处理也很麻烦:
    比如:
    System.out.println("2,//test \"3,/* test */");  //4, test
    比如
    String test="//\"\"";//String str="";必须把 注释 和 引用 结合起来判断
    处理起来超复杂有没有比较好的解决方法?
      

  4.   

    而且,
    >使用栈来找出成对出现的字符或者字符串
    处理起来会慢吧,当我的TEXT比较大的时候
      

  5.   

    处理起来会慢吧,当我的TEXT比较大的时候
    --------
    楼主看来没有真正了解。
    正则表达式是一种非常低效的手段,而且必须把被匹配的字符串全部载入。而我说的办法恰好可以解决大数据的问题,使用栈本来就是只需要一个字符一个字符的读进来,不需要载入全部数据。
    你说处理麻烦,我倒是不赞同。
    实际上,需要处理的字符仅限于下面几个:
    /(并且判断下面一个字符是否为*或者/,表示注释开始)
    *(并且判断下面一个字符是否是/,表示注释结束)
    "(先搜索栈内是否有",然后决定是否为字符串开始还是结束)
    \(这个是转义字符,只有下面一个字符是"才需要处理,证明这个不是表示字符串的开始或者结束)
      

  6.   

    仔细研究一下 StreamTokenizer
      

  7.   

    使用栈:得到运行效率,编程复杂
    使用正则表达式:效率不是最高,编程简单
    我曾经使用过的方法是:正则表达式,在此略说一下:1. 采用 3 个正则表达式(java.util.regex.Pattern ptn[3]),分别匹配 "字符串",/* 注释 */,和 // 注释2. 从文件开始进行 matcher()。(得到java.util.regex.Matcher)3. 谁第一个找到(得到的 Matcher.start()最小),那么,start() 到 end() 之间就属于这种类型。4. 然后从刚才找的 end() 处开始处所有的 Pattern 重新进行 matcher()这样,你就知道了从哪个位置到哪个位置是什么成分了
      

  8.   

    我有一个页面就是这么写的:你把下面这段代码放入
    http://www29.websamba.com/sswater/examples/grammar/你可以看到我做的效果。
    /**
     * 1,test
     */
    public class Test {
        public void test() {
            System.out.println("2,//test 3,/* test */");  //4, test
        }
    }
      

  9.   

    >4. 然后从刚才找的 end() 处开始处所有的 Pattern 重新进行 matcher()好像不能用
    matcher.appendReplacement(sb, "replacement");
    吧,下面的代码有问题吧:
    String text = "/**"
                +"* 1,test"
                +"*/"
                +"public class Test {<br>"
                +"      public void test() {<br>"
                +"          System.out.println(\"2,//test 3,/* test */\");  //4, test<br>"
                +"      }<br>"
                +"}<br>";
            
            String strWqPattern = "\"(?:\\\"|[^\"])*\"?";
            String strCommentLine = "//";
            String strCommentBlock = "/\\*(?:[^\\*]/|\\*[^/]|[^\\*/])*\\*/?";
            
            Pattern wqPattern = Pattern.compile(strWqPattern);
            Matcher wqMatcher = wqPattern.matcher(text);
            
            Pattern commentPattern = Pattern.compile(strCommentLine);
            Matcher commentMatcher = commentPattern.matcher(text);
            
            Pattern commentBlockPattern = Pattern.compile(strCommentBlock);
            Matcher commentBlockMatcher = commentBlockPattern.matcher(text);
            
            StringBuffer regexRet = new StringBuffer();
            int matchStartIndex = 0;
            while(true) {
                int nWqMatcher = wqMatcher.find() ? wqMatcher.start():Integer.MAX_VALUE;
                int nCommentMatcher = commentMatcher.find() ? commentMatcher.start():Integer.MAX_VALUE;
                int nCommentBlockMatcher = commentBlockMatcher.find() ? commentBlockMatcher.start():Integer.MAX_VALUE;
                
                if (nWqMatcher == Integer.MAX_VALUE 
                        && nCommentMatcher == Integer.MAX_VALUE 
                        && nCommentBlockMatcher == Integer.MAX_VALUE) {
                    break;
                }
                
                if ( nWqMatcher < nCommentMatcher && nWqMatcher < nCommentBlockMatcher ) {
                    // match "..."
                    wqMatcher.appendReplacement(regexRet, "<div style=red>$0</div>");
    //                text = wqMatcher.replaceAll("<div style=red>$0</div>");
    //                matchStartIndex = wqMatcher.end() + 21;
                } else if (nCommentMatcher < nWqMatcher && nCommentMatcher < nCommentBlockMatcher ) {
                    // match //
                    wqMatcher.appendReplacement(regexRet, "<div style=green>$0</div>");
    //                text = commentMatcher.replaceAll("<div style=green>$0</div>");
    //                matchStartIndex = commentMatcher.end() +  23;
                } else if (nCommentBlockMatcher < nWqMatcher && nCommentBlockMatcher < nCommentMatcher ) {
                    // match /* ... */
                    
                    wqMatcher.appendReplacement(regexRet, "<div style=green2>$0</div>");
    //                text = commentBlockMatcher.replaceFirst("<div style=green2>$0</div>");
    //                matchStartIndex = commentBlockMatcher.end() + 25;
                }
            }
            
            System.out.println(regexRet);
      

  10.   

    上面的代码还不正确,
    我想确认一下,是不是每次匹配之后,还得
    〉从刚才找的 end() 处重新构造新的TEXT/Pattern/Match?
      

  11.   

    道理其实是这样的:比如 => "/*  */"  /**/Pattern(字符串) 找到的位置是 第一个字符(下标=0)
    Pattern(注释)   找到的位置时 第二个字符(下标=1)因为先找到的是字符串,因此就有一种可能是:所找到的注释可能是字符串内部的?
    所以需要从字符串结束的地方重新找注释。其实更优化的办法是:将 Pattern(注释) 找到的位置和 Pattern(字符串) 的结束位置进行比较大小:(1)如果 "Pattern(注释) 找到的位置" < "Pattern(字符串) 找到的结束位置",则说明是在字符串内部,这时肯定需要从 "Pattern(字符串) 找的结束位置" 重新匹配。
    (2)如果 "Pattern(注释) 找到的位置" < "Pattern(字符串) 找到的结束位置",实际上不需要重新找了。
      

  12.   

    String strWqPattern = "\".*?\"";
            String strCommentLine = "//[^\\r\\n]*";
            String strCommentBlock = "/\\*.*?\\*/";
      

  13.   

    问题是找到之后 要经过替换
    比如需要把["*"]->[<div>"*"</div>]; [//*]->[<div2>//*[/div2]]; [/* * */]->...,经过替换后
    matcher[1,2,3]所对应的text就不一样了
    这样的话,岂不要需要用替换后的text重新构造matcher进行匹配?
      

  14.   

    请教: sswater(光杆兵)你是怎么解决:
    〉matcher[1,2,3]所对应的text就不一样了
    这个问题的?如果每次替换后, 都 需要用替换后的text重新构造matcher进行匹配-〉替换,
    效率上岂不?
      

  15.   

    我没有一边 match 一边替换。我是分析过程中,将分析结果保存起来,将语法分析完了以后,再去拼凑出最终结果的。"<span class=aaa>" + str.subtring( posstart, posend ) + "</span>"这个话题好像越说越复杂,我的目标是分析语法成分,不知道你的目标和我有没有多大的差别。你在问题中说到,替换 test 为 xxxx 或者 yyyy。可以采取的办法是,先把语法分析结果保存到一个地方,再去找 test,根据找到的 test 的位置去判断是属于何种语法成分。
      

  16.   

    >我没有一边 match 一边替换。我是分析过程中,将分析结果保存起来,将语法分析完了以后,再去拼凑出最终结果的。我想也只能这样了,thanks a lot, 呆会结帐!