使用正则表达式查找java注释(多行和单行)

时间:2016-06-01 18:57:47

标签: java python regex

我在http://regexlib.com/

在线找到了以下正则表达式
(\/\*(\s*|.*?)*\*\/)|(\/\/.*)

以下匹配似乎效果很好:

// Compute the exam average score for the midterm exam

/**
* The HelloWorld program implements an application that
*/

但它也倾向于匹配

http://regexr.com/foo.html?q=bar

至少从//

开始

我刚接触正则表达式和一个完全婴儿,但我读到如果你在开始时插入一个插入符号,它会强制匹配从该行的开头开始,但这似乎并不是在RegExr上工作。

我使用以下内容:

^(\/\*(\s*|.*?)*\*\/)|(\/\/.*)$

2 个答案:

答案 0 :(得分:0)

您正在寻找的正则表达式允许评论开始(///*)出现在任何位置,除了每个正则表达式中导致可以包含其中的子字符串的标记。如果查看lexical structure of java language,您会看到内部包含///*的唯一词法元素是字符串文字,因此要匹配字符串中的注释你必须匹配所有字符串(因为没有字符串文字之前你的匹配恰好开始一个字符串文字 - 并在里面包含你的评论)

因此,之前的字符串应该由任何不以字符串文字开头的有效字符串组成(没有结束),因此,它可以被任意数量的字符串文字舍入任何不在其间形成字符串文字的字符串。如果考虑字符串文字,则应与以下内容匹配:

\"()*\"

并且括号内部必须填充的内容不能是\n,单",单\,也不能是unicode文字{{1}导致有效\uxxxx(java禁止使用普通java字符编码为unicode序列,因此最后一种情况不适用)但可以是转义"或转义{{} 1}},所以这导致

\\

这可以重复任意次数,并且在任何字符不是\"之前(应该开始考虑最后一部分):

\"([^\\\"\n]|\\.)*\"

好吧,我们的有效字符串的前一部分应与此字符串匹配,然后是注释字符串,它可以是两种形式中的任何一种:

"

([^\\"](\"([^\\\"\n]|\\.)*\")?)*

(这是一个斜杠,一个星号(转义),以及可能有的任何数量的东西:不同于\/\/[^\n]*$ /\*([^\*]|\*[^\/])*\*\/ 的东西,后跟不是{{1}的东西},最终达到*序列)

这些可以在另一个组中分组,如:

*

最后,我们的表达式显示:

/

但是你应该小心你的匹配评论不是从头开始,而是在第4组(在第4个左括号的标记中)并且正则表达式应该与开头的字符串匹配,请参阅demo

注意

认为您不仅要匹配评论,还要匹配之前的文本。这使得结果匹配由您想要和匹配之前的匹配组成。另外想想如果你按顺序尝试这个带有几个注释的regexp,它只会匹配最后一个,因为我们没有涉及*/序列的情况(注释也可以嵌入到注释中,但是考虑到这种情况也会让你永远讨厌正则表达式。处理这个问题的正确方法是编写一个(\/\/[^\n]*\n|\/\*([^\*]|\*[^\/])*\*\/) 规范来获取java标记,你只能得到它们,但这超出了范围这个解释。看一个可能有效的例子here

答案 1 :(得分:-1)

你可以尝试这种模式:

(?ms)^[^'"\n]*?(?:(?:"(?:\\.|[^"])*"|'\\?.')[^'"\n]*?)*((?:(?://[^\n]*|/\*.*?\*/)[ \t]*)+)

这会捕获第1组中的注释,但前提是注释不在字符串中。 Demo.

故障:

(?ms)                 multiline flag, makes ^ match at the start of a line
                      singleline flag makes . match newlines
^                     start of line
[^'"\n]*?             match anything but " or ' or newline
(?:                   then, any number strings:
    (?:
        "             start with a quote...
        (?:           ...followed by any number of...
            \\.       ...a backslash and the escaped character
        |             or
            [^"]      any character other than "
        )*
        "             ...and finally the closing quote
    |                 or...
        '\\?.'        a single character in single quotes, possibly escaped
    )
    [^'"\n]*?         and everything up to the next string or newline
)*
(                     finally, capture (any number of) comments:
    (?:
        (?:           either...
            //[^\n]*  a single line comment
        |             or
            /\*.*?\*/ a multiline comment
        )
        [ \t]*        and any subsequent comments if only separated by whitespace
    )+
)