Как уже отмечали другие, если конечной целью является только удаление строк, начинающихся с //#
, по соображениям производительности вам, вероятно, лучше использовать grep
или sed
:
grep -v '^\/\/#' filename.txt > filename.stripped.txt
sed '/^\/\/#/d' filename.txt > filename.stripped.txt
или
sed -i '/^\/\/#/d' filename.txt
, если вы предпочитаете редактирование на месте.
Обратите внимание, что в Perl ваше регулярное выражение будет
m{^//#}
, который соответствует двум слешам, за которыми следует # в начале строки.
Обратите внимание, что вы избегаете "обратного слешита", используя оператор сопоставления m{pattern}
вместо более привычного /pattern/
. Обучайтесь этому синтаксису рано, поскольку это простой способ избежать чрезмерного побега. Вы можете написать m{^//#}
так же эффективно, как m%^//#%
или m#^//\##
, в зависимости от того, что вы хотите сопоставить. Стремитесь к ясности - регулярные выражения достаточно сложны для расшифровки без колючего леса с обратными слешами, которые убивают читабельность. Серьезно, m/^\/\/#/
выглядит как аллигатор с колотым зубом и пломбой или крошечной ASCII-картиной Альп.
Одна проблема, которая может возникнуть в вашем скрипте, заключается в том, что весь файл превращается в строку, символы новой строки и все. Чтобы защититься от этого случая, используйте модификатор / m (multiline) в регулярном выражении:
m{^//#}m
Это позволяет ^ совпадать в начале строки и после новой строки. Вы могли бы подумать, что есть способ обрезать или сопоставить строки, соответствующие m{^//#.*$}
, с использованием модификаторов регулярных выражений /g
, /m
и /s
в случае, когда вы записали файл в строку, но не Я не хочу делать его копию (сначала задается вопрос, почему он был добавлен в строку.) Это должно быть возможным, но уже поздно, и я не вижу ответа. Однако, один «простой» способ сделать это:
my $cooked = join qq{\n}, (grep { ! m{^//} } (split m{\n}, $raw));
, хотя это создает копию вместо редактирования на месте исходной строки $raw
.