<p>您要查找的regex允许注释开头(<code>//</code>或<code>/*</code>)出现在除每个regexp之外的任何地方,这些regexp会生成可以包含这些子字符串的标记。如果你看一下<a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html" rel="nofollow">lexical structure of java language</a>,你会发现唯一可以包含<code>//</code>或<code>/*</code>的词法元素是string literal,因此,要匹配字符串中的注释,您必须匹配所有字符串(因为在匹配之前没有字符串文字<strong>,而匹配恰好以字符串文字开头,并且在字符串文字中包含您的注释)</p>
<p>因此,注释前的字符串<em>应该由任何不以字符串文字开头(没有结尾)的有效字符串组成,因此,它可以由任意数量的字符串文字和中间不形成字符串文字的任何字符串四舍五入。如果考虑字符串文字,则应与以下内容匹配:</p>
<pre><code>\"()*\"
</code></pre>
<p>括号内必须填充不能是<code>\n</code>、单个<code>"</code>、单个<code>\</code>的内容,也不能是导致有效<code>"</code>的unicode文本<code>\uxxxx</code>(java禁止将普通java字符编码为unicode序列,因此最后一种情况不适用),但可以是转义的<code>\\</code>或者一个转义的<code>\"</code>,所以这导致</p>
<pre><code>\"([^\\\"\n]|\\.)*\"
</code></pre>
<p>并且这可以选择性地重复任意次数,并且在任何不是<code>"</code>(应该从最后一部分开始考虑)的字符前面:</p>
<pre><code>([^\\"](\"([^\\\"\n]|\\.)*\")?)*
</code></pre>
<p>好吧,我们的有效字符串的前一部分应该与这个字符串匹配,然后是注释字符串,它可以是两种形式中的任何一种:</p>
<pre><code>\/\/[^\n]*$
</code></pre>
<p>或者</p>
<pre><code>/\*([^\*]|\*[^\/])*\*\/
</code></pre>
<p>(这是一个斜杠、一个星号(转义)和任意数量的事物:不是<code>*</code>就是<code>*</code>后面跟一些不是<code>/</code>的事物,最后到达<code>*/</code>序列)</p>
<p>可以将它们分组到另一个组中,如:</p>
<pre><code>(\/\/[^\n]*\n|\/\*([^\*]|\*[^\/])*\*\/)
</code></pre>
<p>最后,我们的表达式显示:</p>
<pre><code>^([^\\"](\"([^\\\"\n]|\\.)*\")?)*(\/\/[^\n]*|\/\*([^\*]|\*[^/])*\*\/)
</code></pre>
<p>但是您应该注意匹配的注释不是从开头开始的,而是在第4组(在第4个左括号中)中开始的,regexp应该从开头匹配字符串,请参见<a href="https://regex101.com/r/gV3uM4/1" rel="nofollow">demo</a></p>
<h2>注意</h2>
<p>认为你不仅匹配了评论,而且匹配了之前的文本。这使得结果匹配由您想要的匹配之前的内容和匹配的内容组成。另外,如果您尝试这个regexp并按顺序添加几个注释,它将只匹配最后一个,因为我们没有讨论<code>/* ... /* .... */</code>序列的情况(注释也是可以嵌入到注释中的东西,但是考虑到这个情况,您将永远恨regexp)。解决这个问题的正确方法是编写一个<code>lex/flex</code>规范来获取java令牌,而您只能获取它们,但这超出了本说明的范围。请参阅一个可能有效的示例<a href="https://regex101.com/r/gV3uM4/3" rel="nofollow">here</a>。你知道吗</p>