使用regex查找java注释(多行和单行)

2024-09-26 22:07:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我在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

至少从//开始

我对regex还不熟悉,完全是个婴儿,但我读到如果你在开头加上一个插入符号,它会强制匹配从行的开头开始,然而这似乎对RegExr不起作用。你知道吗

我正在使用以下命令:

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

Tags: thecomanhttpforprogramhelloworldscore
2条回答

您要查找的regex允许注释开头(///*)出现在除每个regexp之外的任何地方,这些regexp会生成可以包含这些子字符串的标记。如果你看一下lexical structure of java language,你会发现唯一可以包含///*的词法元素是string literal,因此,要匹配字符串中的注释,您必须匹配所有字符串(因为在匹配之前没有字符串文字,而匹配恰好以字符串文字开头,并且在字符串文字中包含您的注释)

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

\"()*\"

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

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

并且这可以选择性地重复任意次数,并且在任何不是"(应该从最后一部分开始考虑)的字符前面:

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

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

\/\/[^\n]*$

或者

/\*([^\*]|\*[^\/])*\*\/

(这是一个斜杠、一个星号(转义)和任意数量的事物:不是*就是*后面跟一些不是/的事物,最后到达*/序列)

可以将它们分组到另一个组中,如:

(\/\/[^\n]*\n|\/\*([^\*]|\*[^\/])*\*\/)

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

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

但是您应该注意匹配的注释不是从开头开始的,而是在第4组(在第4个左括号中)中开始的,regexp应该从开头匹配字符串,请参见demo

注意

认为你不仅匹配了评论,而且匹配了之前的文本。这使得结果匹配由您想要的匹配之前的内容和匹配的内容组成。另外,如果您尝试这个regexp并按顺序添加几个注释,它将只匹配最后一个,因为我们没有讨论/* ... /* .... */序列的情况(注释也是可以嵌入到注释中的东西,但是考虑到这个情况,您将永远恨regexp)。解决这个问题的正确方法是编写一个lex/flex规范来获取java令牌,而您只能获取它们,但这超出了本说明的范围。请参阅一个可能有效的示例here。你知道吗

您可以尝试以下模式:

(?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
    )+
)

相关问题 更多 >

    热门问题