Вы слишком усложняете вещи, балуясь $&
. s///g
возвращает количество замен, выполненных при использовании в скалярном контексте, так что вы можете сделать все это за один снимок без необходимости подсчитывать совпадения вручную или отслеживать позицию каждого совпадения:
#!/usr/bin/env perl
use strict;
use warnings;
my $text = 'James Watt, a pioneer of wattage engineering';
my $doubles = $text =~ s/(\w)\1/($1$1)/g;
print "$doubles $text\n";
Выход:
4 James Wa(tt), a pion(ee)r of wa(tt)age engin(ee)ring
Edit: OP заявил в комментариях, что рассматриваемое упражнение говорит, что не следует использовать =~
, так что вот решение, не основанное на регулярном выражении, так как все совпадения с регулярным выражением используют =~
(неявно или явно ):
#!/usr/bin/env perl
use strict;
use warnings;
my $text = 'James Watt, a pioneer of wattage engineering';
my $doubles = 0;
for my $i (reverse 1 .. length $text) {
if (substr($text, $i, 1) eq substr($text, $i - 1, 1)) {
$doubles++;
substr($text, $i - 1, 2) = '(' . substr($text, $i - 1, 2) . ')';
}
}
print "$doubles $text\n";