Как я могу удалить блокирующие комментарии с помощью Perl?
Вопрос
Я работаю над препроцессором, который анализирует DSL.Моя цель - удалить комментарии.Возможность блокировать комментарии разграничена %%
до и после.Мне не нужно беспокоиться о том, что %% находится в строках, по определению языка.
Я использую это s///
регулярное выражение.К сожалению, кажется, что это соответствует всему и стирает это:
#Remove multiline comments.
$text_string =~ s/%%.*%%//msg;
Что я делаю не так?
Решение
первое, что вы можете сделать, это сделать его нежадным:
.*?
в противном случае,
%% немного текста %%
реальный контент
%% другой текст %%
все будет уничтожено.
Другие советы
От perlfaq6:Что это значит, что регулярные выражения являются жадными?Как я могу обойти это?
Большинство людей имеют в виду, что жадные регулярные выражения совпадают настолько, насколько это возможно.Технически говоря, на самом деле это кванторы (?, *, +, {}) которые являются жадными, а не весь шаблон;Perl предпочитает локальную жадность и немедленное удовлетворение общей жадности.Чтобы получить нежадные версии одних и тех же кванторов, используйте (??, *?, +?, {}?).
Пример:
$s1 = $s2 = "I am very very cold";
$s1 =~ s/ve.*y //; # I am cold
$s2 =~ s/ve.*?y //; # I am very cold
Обратите внимание, как вторая замена перестала соответствовать, как только столкнулась с буквой "y ".Тот самый *?квантификатор эффективно сообщает движку регулярных выражений найти соответствие как можно быстрее и передать управление всему, что находится следующим на очереди, как вы сделали бы, если бы играли в hot potato.
предполагая, что вы прочитали весь код в переменную $str и между %% и %% нет возможности появления одного %, вы могли бы использовать это.
$str =~ s/%%([^%]+)%%// g;