Попробуйте это для размера:
my @numbers = ($moyLargRectNom, $moyHautRectNom, $moyLargRectNom, $moyHautRectNom, $moyLargRectMat, $moyHautRectMat, $moyLargRectMat, $moyHautRectMat);
my @temp = split / /, $ligne;
for(@temp) {
if(/^\W*\d\W*$/) {
my $num = shift @numbers;
s/\d+/$num/;
}
}
$ligne = join " ", @temp;
Это составляет список @temp
, основанный на «словах» (приблизительно) в $ligne
. Он создает еще один список, @numbers
, который представляет собой список чисел, которые вы хотите заменить в списке, в том порядке, в котором вы хотите, чтобы они что-то заменяли. Затем он проходит @temp
, один за другим, и если данный элемент является числом (то есть соответствует регулярному выражению /^\W*\d\W*$/
, что означает, что он не имеет словесных символов (поэтому это не "champs4") и имеет по крайней мере одно число - это будет соответствовать «25346)» в дополнение к «25346»), а затем заменить числовую часть первым значением из @numbers
. И теперь, когда я проверил это, я могу заверить вас, что это действительно работает!
Я считаю, что более короткая реализация может быть достигнута с помощью map
, но для вас это будет достаточно хорошо.
Преимущества этого подхода для вашего подхода:
Во-первых, это решение является масштабируемым. Чтобы заменить более восьми чисел вашим решением, вам нужно написать новое регулярное выражение. Чтобы заменить более восьми чисел моим решением, просто добавьте еще несколько записей к @numbers
. Этот код может быть помещен в подпрограмму, которая принимает строку для изменения и список чисел для изменения, и вам не придется беспокоиться о том, передали ли они правильное количество чисел или имеют ли они правильный формат.
Во-вторых, это немного легче понять с помощью беглого взгляда. До тех пор, пока вы используете регулярное выражение, его очень сложно проанализировать визуально. Даже если это работает, когда-нибудь кому-то может понадобиться изменить ваш код, чтобы сделать что-то другое. Если вы используете огромное регулярное выражение, переписчик (возможно, вы) просто покачает головой, выделит ваш код и нажмете «Удалить», а затем напишет новый код, чтобы сделать это. Благодаря этому они могут легко видеть, что происходит в вашем коде, и, если им нужно внести в него изменения, они могут.
В-третьих, если вы хотите жестко закодировать указанное количество замен, вы также можете сделать это:
my @numbers = ($moyLargRectNom, $moyHautRectNom, $moyLargRectNom, $moyHautRectNom, $moyLargRectMat, $moyHautRectMat, $moyLargRectMat, $moyHautRectMat);
my @temp = split / /, $ligne;
my $max_replacements = 8;
for(@temp) {
if(/^\W*\d\W*$/) {
my $num = shift @numbers;
s/\d+/$num/;
last unless --$max_replacements;
}
}
$ligne = join " ", @temp;
В качестве примечания (которое применялось ранее, но все еще применяется), это не будет работать для чисел с плавающей запятой - /^\W*\d\W*$/
будет соответствовать числам с плавающей запятой, но s/\d+/$num/
не заменит числа с плавающей запятой, только целую часть , Если вы обнаружите, что вам нужны числа с плавающей запятой, измените эту строку:
s/\d+/$num/;
На это:
s/\d+|(?:\d+)?\.\d+/$num/;
Это должно соответствовать числам с плавающей запятой.