s ///
действительно возвращает количество замен, сделанных в скалярном контексте. Из perlop (курсив добавлен):
s / PATTERN / REPLACEMENT / msixpogce
Ищет строку для шаблона и, если найден, заменяет его шаблон с текстом замены, а возвращает количество произведены замены . В противном случае возвращается false (в частности, пустая строка).
Ваша проблема в том, что вы не вызывали s ///
в скалярном контексте. Вы вызвали его в контексте списка, а затем оценили присвоение (пустому списку) в скалярном контексте. Назначение списка в скалярном контексте возвращает количество элементов, созданных правой частью выражения. Поскольку s ///
возвращает одно значение (как в контексте списка, так и в скалярном контексте), количество элементов всегда равно единице, даже если s ///
ничего не сделали.
perl -E "$s='aaabbcc'; $c=()=$s=~s/x/y/g; say qq'$c-$s'" # prints "1-aaabbcc"
Чтобы вызвать s ///
в скалярном контексте, опустите псевдооператор = () =
.
perl -E "$s='aaabbcc'; $c=$s=~s/a/x/g; say qq'$c-$s'" # prints "3-xxxbbcc"