Что касается обработки вложенных комментариев, хотя верно то, что вы не можете использовать регулярное выражение Java для сопоставления с крайним комментарием, вы можете создать комментарий, который будет соответствовать самый внутренний комментарий (с некоторыми заметными исключениями - см. предостережения ниже). (Обратите внимание, что выражение: \(\*(.*?)\*\)
НЕ будет работать в этом случае, так как оно не соответствует внутреннему комментарию.) Ниже приведена протестированная Java-программа, которая использует (строго прокомментированное) регулярное выражение, которое соответствует только самым внутренним комментариям, и применяет это итеративно, чтобы правильно удалить вложенные комментарии:
public class TEST {
public static void main(String[] args) {
String subjectString = "out1 (* c1 *) out2 (* c2 (* c3 *) c2 *) out3";
String regex = "" +
"# Match an innermost pascal '(*...*)' style comment.\n" +
"\\(\\* # Comment opening literal delimiter.\n" +
"[^(*]* # {normal*} Zero or more non'(', non-'*'.\n" +
"(?: # Begin {(special normal*)*} construct.\n" +
" (?! # If we are not at the start of either...\n" +
" \\(\\* # a nested comment\n" +
" | \\*\\) # or the end of this comment,\n" +
" ) [(*] # then ok to match a '(' or '*'.\n" +
" [^(*]* # more {normal*}.\n" +
")* # end {(special normal*)*} construct.\n" +
"\\*\\) # Comment closing literal delimiter.";
String resultString = null;
java.util.regex.Pattern p = java.util.regex.Pattern.compile(
regex,
java.util.regex.Pattern.COMMENTS);
java.util.regex.Matcher m = p.matcher(subjectString);
while (m.find())
{ // Iterate until there are no more "(* comments *)".
resultString = m.replaceAll("");
m = p.matcher(resultString);
}
System.out.println(resultString);
}
}
Вот краткая версия регулярного выражения (в собственном формате регулярного выражения):
\(\*[^(*]*(?:(?!\(\*|\*\))[(*][^(*]*)*\*\)
Обратите внимание, что это регулярное выражение реализует эффективную технику Джеффри Фридла "Развертывание цикла" и довольно быстро. (См .: Освоение регулярных выражений (3-е издание) ).
Предостережения: Это, безусловно, НЕ будет работать правильно, если в строковом литерале присутствует какой-либо разделитель комментариев (т.е. (*
или *)
) и, следовательно, НЕ должен использоваться для общего анализа. Но такое регулярное выражение удобно использовать время от времени - например, для быстрого и грязного поиска в редакторе.
См. Также мой ответ на аналогичный вопрос для кого-то, кто хочет обрабатывать вложенные комментарии в стиле C.