Regex для разработчиков
-
09-06-2019 - |
Вопрос
Я пытался найти регулярное выражение, которое позволило бы мне искать определенную строку, автоматически пропуская комментарии.У кого-нибудь есть такой RE или кто-нибудь знает о нем?Даже не нужно быть достаточно сложным, чтобы пропустить #if 0
блоки;Я просто хочу, чтобы это пропустили //
и /*
блоки.Обратный вариант, то есть поиск только внутри блоков комментариев, тоже будет очень полезен.
Среда:ВС 2003
Решение
Это более сложная проблема, чем может показаться на первый взгляд, поскольку вам необходимо учитывать токены комментариев внутри строк, токены комментариев, которые сами закомментированы, и т. д.
Я написал синтаксический анализатор строк и комментариев для C#, посмотрим, смогу ли я найти что-нибудь, что поможет...Я обновлю, если найду что-нибудь.
РЕДАКТИРОВАТЬ:...Итак, я нашел свой старый проект «codemasker».Оказывается, я делал это поэтапно, а не с помощью одного регулярного выражения.По сути, я просматриваю исходный файл в поисках начальных токенов, а когда нахожу один, я затем ищу конечный токен и маскирую все, что между ними.При этом учитывается контекст стартового токена...если вы найдете токен для «начала строки», вы можете безопасно игнорировать токены комментариев, пока не найдете конец строки, и наоборот.Как только код замаскирован (я использовал направляющие в качестве масок и хеш-таблицу для отслеживания), вы можете безопасно выполнить поиск и замену, а затем, наконец, восстановить замаскированный код.
Надеюсь, это поможет.
Другие советы
Будьте особенно осторожны со струнами.Строки часто имеют escape-последовательности, которые вы также должны соблюдать при поиске их конца.
Так, например. "This is \"a test\""
.Вы не можете слепо искать двойные кавычки для завершения.Также остерегайтесь фразы ``"This is \"`, которая показывает, что вы не можете просто сказать «если перед двойной кавычкой не стоит обратная косая черта».
Короче говоря, проведите несколько жестоких модульных тестов!
Регулярное выражение — не лучший инструмент для этой работы.
Часто задаваемые вопросы по Perl:
Комментарии С:
#!/usr/bin/perl
$/ = undef;
$_ = <>;
s#/\*[^*]*\*+([^/*][^*]*\*+)*/|([^/"']*("[^"\\]*(\\[\d\D][^"\\]*)*"[^/"']*|'[^'\\]*(\\[\d\D][^'\\]*)*'[^/"']*|/+[^*/][^/"']*)*)#$2#g;
print;
Комментарии С++:
#!/usr/local/bin/perl
$/ = undef;
$_ = <>;
s#//(.*)|/\*[^*]*\*+([^/*][^*]*\*+)*/|"(\\.|[^"\\])*"|'(\\.|[^'\\])*'|[^/"']+# $1 ? "/*$1 */" : $& #ge;
print;
Я бы сначала сделал копию и удалил комментарии, а затем выполнил обычный поиск по строке.