下面是一段标准的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,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
也就是说我们碰到"先入栈,后面碰到非"的字符(包括转义字符\")我们都可以认为是字符串里面的内容,直到一个碰到应该成对出现的",就把之前栈内的"弹出。
所以当我们碰到注释字符的时候,先查看栈内是否有围匹配的",有则说明是字符串内,不予考虑。否则,则认为这是注释。
比如:
System.out.println("2,//test \"3,/* test */"); //4, test
比如
String test="//\"\"";//String str="";必须把 注释 和 引用 结合起来判断
处理起来超复杂有没有比较好的解决方法?
>使用栈来找出成对出现的字符或者字符串
处理起来会慢吧,当我的TEXT比较大的时候
--------
楼主看来没有真正了解。
正则表达式是一种非常低效的手段,而且必须把被匹配的字符串全部载入。而我说的办法恰好可以解决大数据的问题,使用栈本来就是只需要一个字符一个字符的读进来,不需要载入全部数据。
你说处理麻烦,我倒是不赞同。
实际上,需要处理的字符仅限于下面几个:
/(并且判断下面一个字符是否为*或者/,表示注释开始)
*(并且判断下面一个字符是否是/,表示注释结束)
"(先搜索栈内是否有",然后决定是否为字符串开始还是结束)
\(这个是转义字符,只有下面一个字符是"才需要处理,证明这个不是表示字符串的开始或者结束)
使用正则表达式:效率不是最高,编程简单
我曾经使用过的方法是:正则表达式,在此略说一下:1. 采用 3 个正则表达式(java.util.regex.Pattern ptn[3]),分别匹配 "字符串",/* 注释 */,和 // 注释2. 从文件开始进行 matcher()。(得到java.util.regex.Matcher)3. 谁第一个找到(得到的 Matcher.start()最小),那么,start() 到 end() 之间就属于这种类型。4. 然后从刚才找的 end() 处开始处所有的 Pattern 重新进行 matcher()这样,你就知道了从哪个位置到哪个位置是什么成分了
http://www29.websamba.com/sswater/examples/grammar/你可以看到我做的效果。
/**
* 1,test
*/
public class Test {
public void test() {
System.out.println("2,//test 3,/* test */"); //4, test
}
}
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);
我想确认一下,是不是每次匹配之后,还得
〉从刚才找的 end() 处重新构造新的TEXT/Pattern/Match?
Pattern(注释) 找到的位置时 第二个字符(下标=1)因为先找到的是字符串,因此就有一种可能是:所找到的注释可能是字符串内部的?
所以需要从字符串结束的地方重新找注释。其实更优化的办法是:将 Pattern(注释) 找到的位置和 Pattern(字符串) 的结束位置进行比较大小:(1)如果 "Pattern(注释) 找到的位置" < "Pattern(字符串) 找到的结束位置",则说明是在字符串内部,这时肯定需要从 "Pattern(字符串) 找的结束位置" 重新匹配。
(2)如果 "Pattern(注释) 找到的位置" < "Pattern(字符串) 找到的结束位置",实际上不需要重新找了。
String strCommentLine = "//[^\\r\\n]*";
String strCommentBlock = "/\\*.*?\\*/";
比如需要把["*"]->[<div>"*"</div>]; [//*]->[<div2>//*[/div2]]; [/* * */]->...,经过替换后
matcher[1,2,3]所对应的text就不一样了
这样的话,岂不要需要用替换后的text重新构造matcher进行匹配?
〉matcher[1,2,3]所对应的text就不一样了
这个问题的?如果每次替换后, 都 需要用替换后的text重新构造matcher进行匹配-〉替换,
效率上岂不?