Я бы оставил это как ряд регулярных выражений. Я не думаю, что он будет более эффективен в вычислительном отношении в качестве одной строки. Необходимое сложное регулярное выражение, вероятно, потребует большого количества возвратов. Во всяком случае, было бы сложнее поддерживать. Я бы просто завернул это в squeeze_whitespace
рутину.
$txt =~ s/^$//ms;
не работает, потому что $
соответствует либо в конце строки непосредственно перед новой строкой . Поэтому, если строка содержит только новую строку, она не будет соответствовать ей.
$txt =~ s/^\n//ms;
не удаляет пустые строки в начале строки, потому что /m
изменяет ^
и $
, чтобы соответствовать началу и концу любой строки. Вам просто повезло с вашими тестовыми данными, что ваша строка начинается с новой строки, поэтому она соответствует этому и остановилась. То же самое со следующим. Используйте \A
и \z
или не спам /ms
.
$txt =~ s{([\t ])+}{$1}g
заменит последовательность вкладок или пробелов только одной вкладкой или пробелом. Однако с чем-то вроде "this \t that"
он выберет последний символ.
Что приводит нас к тестированию.
use Test::More;
note "test tab and whitespace squeezing"; {
is squeeze_whitespace("this that"), "this that";
is squeeze_whitespace("this\t\tthat"), "this\tthat";
is squeeze_whitespace("this \t that up ", "this that up";
}
note "test begin/end newline stripping"; {
is squeeze_whitespace("\nfoo\n"), "foo", "newlines removed from the start and end";
is squeeze_whitespace("foo\nbar"), "foo\nbar", "newlines not eaten if there's no newline at the start";
}
и т. Д.