Это хорошо, и единственная проблема, которую я вижу, заключается в том, что вы, возможно, неправильно подсчитали, поскольку substr счетчики начинаются с 0. Еще одна вещь заключается в том, что каждая строка должна быть записана в выходной файл, поэтому потеряйте последний else
и просто напишите строку, изменена она или нет. †
Однако я бы предложил улучшение. Поиск символа путем запуска регулярного выражения для каждого ключа не требуется, это расточительно и дорого. Есть и другие способы, более простые и эффективные.
Используя substr
, нам нужны два вызова, когда его замена определяется динамически
substr $line, 16, 1, $repl{ substr $line, 16, 1 };
Это заменяет подстроку длиной 1
на позиция 17 (отсчет начинается с 0) со значением в %repl
для ключа, который является подстрокой длины 1
в позиции 17.
Но эта строка сама по себе может иметь проблему, если строка была короче требуемой позиции. Фактически, это относится к строке, которая получает замену {
и состоит всего из 44 символов. Учитывая довольно «специфическое c» поведение substr
с крайними случаями, лучше не добираться до «исправлений», а проверять
# for $col == 45 (etc)
if (length $line >= $col) {
substr $line, $col-1, 1, $repl{ substr $line, $col-1, 1 };
}
Эти позиции могут быть подготовлены в виде массива, чтобы избежать разбросанных магов c числа или скаляры.
Другой способ - использовать регулярное выражение
$line =~ s/.{16}\K(.)/$repl{$1}/;
Это соответствует 16 символам, а \K
отбрасывает эти совпадения, поэтому их не нужно возвращать, и следующий символ захватывается и заменяется его значением в ha sh. Теперь, возможно, несуществующая позиция (за концом строки) не требует специальной обработки, поскольку совпадение просто не выполняется.
Любой из этих двух вышеупомянутых может использоваться вместо foreach
циклов по %repl
ключи и ваш код должны работать как есть, за исключением ветки else
, которую нужно удалить, а $line
просто напечатать. Я также надеюсь, что у вас есть
use warnings;
use strict;
где-то в начале, так как они настоятельно рекомендуются в каждой программе.
Соответствие строки любой 6
/ 7
/ 8
в порядке, но вместо этого вы можете создать ha sh с этими числами в качестве ключей, а их значениями будут ссылки на код, выполняющие необходимые замены. Если эти числа меняются часто (или их может быть намного больше), подумайте о том, чтобы сделать что-то подобное.
† Наконец, print $ww $_;
в ветке else
будет выводить предупреждения, поскольку если актуализатор используется в условии while
($line
), то $_
больше не предоставляется (он не определен).
Однако, вероятно, это вопрос публикации, поскольку он использует $ww
, в то время как определенный дескриптор - $wr
, и есть несколько других опечаток.