爪哇 - 正则表达式查找代码中的注释(Java - regular expression findi

2019-09-03 10:40发布

与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");

任何意见或想法从正则表达式有什么不同? 提前致谢。

Answer 1:

您可以通过现在已经放弃了这一点,但我对这个问题很感兴趣。

我相信这是一个部分解决方案...

本机的正则表达式:

//.*|("(?:\\[^"]|\\"|.)*?")|(?s)/\*.*?\*/

在Java:

String clean = original.replaceAll( "//.*|(\"(?:\\\\[^\"]|\\\\\"|.)*?\")|(?s)/\\*.*?\\*/", "$1 " );

这似乎妥善处理嵌入到字符串以及正确转义字符串内的报价评论。 我把它的几件事情来检查,但没有详尽。

有一个在所有的“”中的代码块将结束之后他们空间的一个折中。 保持这个简单而解决该问题会因为需要处理干净是非常困难的:

int/* some comment */foo = 5;

一个简单的Matcher.find / appendReplacement环可以用一个空间更换前有条件检查组(1)和只会是行的代码屈指可数。 仍然不是一个完整的解析器,也许更简单。 (太多,如果有人有兴趣,我可以添加匹配循环。)



Answer 2:

最后一个例子是没有问题的,我认为:

/* 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;

...什么是无效的代码。 因此,更好地替换您的意见" " ,而不是""



Answer 3:

我认为使用正则表达式100%正确的解决方案要么是不人道或不可能的(考虑到逃逸,等等)。

我认为最好的办法是使用ANTLR-我相信,他们甚至提供您可以使用Java语法。



Answer 4:

我结束了这个解决方案。

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;
    }
}


Answer 5:

另一种方法是使用一些库支持AST解析,对于如org.eclipse.jdt.core有你需要做到这一点,更多的所有API。 但随后,这只是一个替代:)



文章来源: Java - regular expression finding comments in code