与Java一点乐趣这个时候。 我想要写一个程序,读取从标准输入代码(由线线,例如),如:
// some comment
class Main {
/* blah */
// /* foo
foo();
// foo */
foo2();
/* // foo2 */
}
发现在它的所有意见,并删除它们。 我试图使用正则表达式,而现在我已经做了这样的事情:
private static String ParseCode(String pCode)
{
String MyCommentsRegex = "(?://.*)|(/\\*(?:.|[\\n\\r])*?\\*/)";
return pCode.replaceAll(MyCommentsRegex, " ");
}
但它似乎没有对所有的情况下,例如工作:
System.out.print("We can use /* comments */ inside a string of course, but it shouldn't start a comment");
任何意见或想法从正则表达式有什么不同? 提前致谢。
您可以通过现在已经放弃了这一点,但我对这个问题很感兴趣。
我相信这是一个部分解决方案...
本机的正则表达式:
//.*|("(?:\\[^"]|\\"|.)*?")|(?s)/\*.*?\*/
在Java:
String clean = original.replaceAll( "//.*|(\"(?:\\\\[^\"]|\\\\\"|.)*?\")|(?s)/\\*.*?\\*/", "$1 " );
这似乎妥善处理嵌入到字符串以及正确转义字符串内的报价评论。 我把它的几件事情来检查,但没有详尽。
有一个在所有的“”中的代码块将结束之后他们空间的一个折中。 保持这个简单而解决该问题会因为需要处理干净是非常困难的:
int/* some comment */foo = 5;
一个简单的Matcher.find / appendReplacement环可以用一个空间更换前有条件检查组(1)和只会是行的代码屈指可数。 仍然不是一个完整的解析器,也许更简单。 (太多,如果有人有兴趣,我可以添加匹配循环。)
最后一个例子是没有问题的,我认为:
/* we comment out some code
System.out.print("We can use */ inside a string of course");
we end the comment */
......因为评论其实结尾"We can use */
。此代码不能编译。
但我还有一个问题的情况下:
int/*comment*/foo=3;
你的格局将转变到这一点:
intfoo=3;
...什么是无效的代码。 因此,更好地替换您的意见" "
,而不是""
。
我认为使用正则表达式100%正确的解决方案要么是不人道或不可能的(考虑到逃逸,等等)。
我认为最好的办法是使用ANTLR-我相信,他们甚至提供您可以使用Java语法。
我结束了这个解决方案。
public class CommentsFun {
static List<Match> commentMatches = new ArrayList<Match>();
public static void main(String[] args) {
Pattern commentsPattern = Pattern.compile("(//.*?$)|(/\\*.*?\\*/)", Pattern.MULTILINE | Pattern.DOTALL);
Pattern stringsPattern = Pattern.compile("(\".*?(?<!\\\\)\")");
String text = getTextFromFile("src/my/test/CommentsFun.java");
Matcher commentsMatcher = commentsPattern.matcher(text);
while (commentsMatcher.find()) {
Match match = new Match();
match.start = commentsMatcher.start();
match.text = commentsMatcher.group();
commentMatches.add(match);
}
List<Match> commentsToRemove = new ArrayList<Match>();
Matcher stringsMatcher = stringsPattern.matcher(text);
while (stringsMatcher.find()) {
for (Match comment : commentMatches) {
if (comment.start > stringsMatcher.start() && comment.start < stringsMatcher.end())
commentsToRemove.add(comment);
}
}
for (Match comment : commentsToRemove)
commentMatches.remove(comment);
for (Match comment : commentMatches)
text = text.replace(comment.text, " ");
System.out.println(text);
}
//Single-line
// "String? Nope"
/*
* "This is not String either"
*/
//Complex */
///*More complex*/
/*Single line, but */
String moreFun = " /* comment? doubt that */";
String evenMoreFun = " // comment? doubt that ";
static class Match {
int start;
String text;
}
}
另一种方法是使用一些库支持AST解析,对于如org.eclipse.jdt.core有你需要做到这一点,更多的所有API。 但随后,这只是一个替代:)