Удалить все комментарии (однострочные / многострочные) и пустые строки из исходного файла

Как удалить все комментарии и пустые строки из исходного файла C#. Имейте в виду, что могут быть вложенные комментарии. Некоторые примеры:

string text = @"//not a comment"; // a comment

/* multiline
comment */ string newText = "/*not a comment*/"; // a comment

/* multiline // not a comment 
/* comment */ string anotherText = "/* not a comment */ // some text here"// not a comment"; // a comment

мы можем иметь гораздо более сложный источник, чем эти три примера выше. Может ли кто-нибудь предложить шаблон регулярного выражения или другой способ решить эту проблему. Я уже просмотрел много вещей через интернет и не смог найти ничего, что работает.

7 ответов


чтобы удалить комментарии, вижу ответ. После этого удаление пустых строк тривиально.


вы можете использовать функцию в ответ:

static string StripComments(string code)
{
    var re = @"(@(?:""[^""]*"")+|""(?:[^""\n\]+|\.)*""|'(?:[^'\n\]+|\.)*')|//.*|/\*(?s:.*?)\*/";
    return Regex.Replace(code, re, "");
}

а затем удалите пустые строки.


к сожалению, это действительно трудно сделать надежно с регулярным выражением без крайних случаев. Я не исследовал очень далеко, но вы могли бы использовать Языковые Службы Visual Studio для разбора замечаний.


если вы хотите идентифицировать комментарии с регулярными выражениями, вам действительно нужно использовать регулярное выражение в качестве токенизатора. То есть, он идентифицирует и извлекает первую вещь в строке, будь то строковый литерал, комментарий или блок материала, который не является ни строковым литералом, ни комментарием. Затем вы хватаете оставшуюся часть строки и вытаскиваете следующий токен из начала.

это позволяет обойти проблемы с контекстом. Если ты просто пытаешься найти что-то в середине ... строка, нет хорошего способа определить, находится ли конкретный "комментарий" внутри строкового литерала или нет-на самом деле трудно определить, где находятся строковые литералы в первую очередь, из-за таких вещей, как \". Но если вы всегда берете первое в строке, легко сказать: "о, строка начинается с ", Так что все до следующего unescaped " больше строк.- Контекст сам о себе позаботится.

таким образом, вы хотели бы три регулярные выражения:

  • тот, который идентифицирует комментарий, начинающийся в начале строки (либо // или /* комментарий).
  • тот, который идентифицирует строковый литерал, начинающийся в начале строки. Не забудьте проверить для обоих " и @" строки; каждый имеет свои собственные крайние случаи.
  • тот, который идентифицирует что-то, что не является ни тем, ни другим, и соответствует до первого, что мог бы быть комментарием или строковый литерал.

написание фактических шаблонов регулярных выражений оставлено как упражнение для читателя, так как для написания и тестирования потребуется несколько часов, и я не хочу делать это бесплатно. (усмешка) но это, безусловно, выполнимо, если у вас есть хорошее понимание регулярных выражений (или есть место, как StackOverflow, чтобы задавать конкретные вопросы, когда вы застряли) и готовы написать кучу автоматических тестов для вашего кода. Следите за этим последним ("чем-нибудь еще") делом, хотя ... вы хотите остановиться прямо перед @ если за ним следует ", но не если это @ чтобы избежать ключевого слова для использования в качестве идентификатора.


Также см. Мой проект для минимизации кода C#:CSharp-Minifier

помимо удаления комментариев, пробелов и разрывов строк из кода, в настоящее время он может сжимать имена локальных переменных и делать другие минификации.


во-первых, вы определенно хотите использовать RegexOptions.SingleLine при создании RegEx экземпляра. Сейчас вы обрабатываете отдельные строки кода.

чтобы похвалить использование RegexOptions.SingleLine опция, вы хотите, чтобы убедиться, что вы используете начало и конец строки якоря (^ и $ соответственно), что касается конкретных случаев, которые у вас есть, вы хотите, чтобы регулярное выражение применялось к весь строка.

Я бы также рекомендовал разбить условия и использовать чередование для обработки небольших случаев, построение большего регулярного выражения из меньших, более простых в управлении выражений.

наконец, я знаю, что это домашнее задание, но разбор программного языка с регулярными выражениями-это упражнение в бесполезности (это не практическое приложение). Это лучше для более структурированных данных. Если вы обнаружите, что в будущем вы хотите делать такие вещи, как это, используйте парсер, который построен для языка, (в этом случае я бы очень рекомендую Рослин).


использовать мой проект, чтобы удалить большинство комментариев. https://github.com/SynAppsDevelopment/CommentRemover

Он удаляет все комментарии к коду full-line, ending-line и XML Doc с некоторыми ограничениями для сложных комментариев, объясненных в readme и source. Это решение C# с интерфейсом WinForms.