Это должно сработать:
my $str = ...;
$str =~ s/ \b(\w) \s+ (\w)\b /$1$2/gx;
Это удаляет пробел между всеми непробельными символами. Не стесняйтесь заменить \S
на более строгий класс символов, если это необходимо. Также могут быть некоторые крайние случаи, связанные с символами пунктуации, с которыми вам нужно иметь дело, но я не могу догадаться, исходя из предоставленной вами информации.
Как подсказывает Эфир, в одном случае это не получается. Вот версия, которая должна работать (хотя и не так чисто, как первая):
s/ \b(\w) ( (?:\s+ \w\b)+ ) /$1 . join '', split m|\s+|, $2/gex;
Мне понравился подход, основанный на тесте Эфира (подражание - самая искренняя форма лести и все такое):
use warnings;
use strict;
use Test::Magic tests => 4;
sub clean {
(my $x = shift) =~ s{\b(\w) ((?: \s+ (\w)\b)+)}
{$1 . join '', split m|\s+|, $2}gex;
$x
}
test 'space removal',
is clean('ab c d') eq 'ab cd',
is clean('a bcd e f gh') eq 'a bcd ef gh',
is clean('a b c') eq 'abc',
is clean('abc d') eq 'abc d';
возвращается:
1..4
ok 1 - space removal 1
ok 2 - space removal 2
ok 3 - space removal 3
ok 4 - space removal 4