Ответ 1
Чтобы удалить комментарии, см. этот ответ. После этого удаление пустых строк тривиально.
Как удалить все комментарии и пустые строки из исходного файла С#. Имейте в виду, что могут быть вложенные комментарии. Некоторые примеры:
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
У нас может быть гораздо более сложный источник, чем три приведенных выше примера. Может ли кто-нибудь предложить шаблон регулярного выражения или другой способ решить эту проблему. Я уже много раз просматривал материал через Интернет и не нашел ничего, что работает.
Чтобы удалить комментарии, см. этот ответ. После этого удаление пустых строк тривиально.
Вы можете использовать функцию в этом ответе:
static string StripComments(string code)
{
var re = @"(@(?:""[^""]*"")+|""(?:[^""\n\\]+|\\.)*""|'(?:[^'\n\\]+|\\.)*')|//.*|/\*(?s:.*?)\*/";
return Regex.Replace(code, re, "$1");
}
И затем удалите пустые строки.
К сожалению, это действительно трудно сделать надежно с регулярным выражением, не имея случаев краев. Я havnt исследовал очень далеко, но вы могли бы использовать Visual Studio Language Services для анализа комментариев.
Если вы хотите идентифицировать комментарии с помощью регулярных выражений, вам действительно нужно использовать регулярное выражение в качестве токенизатора. I.e., он идентифицирует и извлекает первое в строке, является ли эта вещь строковым литералом, комментарием или блоком данных, который не является ни строковым литералом, ни комментарием. Затем вы берете оставшуюся часть строки и вытаскиваете следующий токен с самого начала.
Это поможет вам решить проблемы с контекстом. Если вы просто пытаетесь найти вещи в середине строки, нет никакого хорошего способа определить, находится ли конкретный "комментарий" внутри строкового литерала или нет - на самом деле трудно определить, где строковые литералы в первую очередь, из-за таких вещей, как \"
. Но если вы всегда берете первое в строке, легко сказать "oh, строка начинается с "
, поэтому все до следующего unescaped "
больше строки". Контекст заботится о себе.
Итак, вам нужно три регулярных выражения:
//
, либо /*
)."
и @"
; каждый из них имеет свои крайние случаи.Написание фактических шаблонов регулярных выражений остается в качестве упражнения для читателя, так как для написания и тестирования все это займет несколько часов, и я не хочу этого делать бесплатно. (усмешка) Но это, безусловно, возможно, если у вас есть хорошее понимание регулярных выражений (или у вас есть такое место, как StackOverflow, чтобы задать конкретные вопросы, когда вы застряли) и готовы написать кучу автоматических тестов для вашего кода. Однако обратите внимание на этот последний ( "что-нибудь еще" ) случай - вы хотите остановиться перед @
, если он следует за "
, но не для @
, чтобы избежать ключевого слова для использования в качестве идентификатор.
Также см. мой проект для минимизации кода С#: CSharp-Minifier
Помимо удаления комментариев, пробелов и разрывов строк из кода, в настоящее время он способен сжимать имена локальной переменной и делать еще одно предупреждение.
Во-первых, вы обязательно захотите использовать RegexOptions.SingleLine
при построении RegEx
. Прямо сейчас вы обрабатываете отдельные строки кода.
Чтобы выразить комплимент использованию опции RegexOptions.SingleLine
, вы должны убедиться, что используете начало и конец строковых якорей (^
и $
соответственно), как и для конкретных случаев, которые вы имеете, вы хотите, чтобы регулярное выражение применялось ко всей строке.
Я также рекомендую разбить условия и использовать alternation для обработки небольших случаев, создавая большее регулярное выражение из меньшего размера, упрощенные для управления выражениями.
Наконец, я знаю, что это домашнее задание, но анализ языка программирования с помощью регулярных выражений - это упражнение в бесполезности (это не практическое приложение). Это лучше для более структурированных данных. Если в будущем вы захотите сделать что-то подобное, используйте синтаксический анализатор, который построен для языка (в этом случае я настоятельно рекомендую Roslyn).
Используйте мой проект, чтобы удалить большинство комментариев. https://github.com/SynAppsDevelopment/CommentRemover
Он удаляет все полнотекстовые, конечные строки и комментарии кода XML Doc с некоторыми ограничениями для сложных комментариев, объясненных в readme и источнике. Это решение С# с интерфейсом WinForms.