my $len= 0; $text =~ s{(\s+)|([^\s<&]+)|(<[^<>]*>)|(&#?\w{1,10};)|(.)}{ if( $1 ) { $len= 0; $1; } elsif( length( $2 ) ) { # $2 is the only case that can be "0" (ie. false) my $res= $2; my $tot= $len + length($res); if( 18 < $tot ) { substr( $res, 18-$tot, 0 )= " "; $res =~ s/(\S{18})(?=\S)/$1 /g; # replace previous with following for [tye]s improvment # $res =~ s/(\S{9,18}\b|\S{18})(?=\S)/$1 /g; $res =~ /(\S*)$/; $len= length( $1 ); } else { $len= $tot; } $res; } elsif( $3 ) { $3; } else { my $res= $4 || $5; my $add= $5 ? 1 : int( length($4)/3 ); $len += $add; if( 18 < $len ) { $len= $add; " $res"; } else { $res; } } }egis; return $text;