c:\@Work\Perl\monks>perl -wMstrict -le
"use warnings;
use strict;
;;
use Test::More 'no_plan';
use Test::NoWarnings;
;;
use Data::Dump qw(pp);
;;
note qq{perl version: $]};
;;
my @TESTS = (
[ undef , qq{} ],
[ qq{} , qq{} ],
[ qq{ } , qq{} ],
[ qq{\n} , qq{} ],
[ qq{\n\t} , qq{ } ],
[ qq{\n\t\x00} , qq{ } ],
[ qq{\n\t \x00} , qq{ } ],
[ qq{\n\t abc 123 xxx\n} , qq{ abc123 xxx} ],
[ qq{\nabc 123\a\b\fxxx\n\t }, qq{abc123 xxx } ],
[ qq{abc 123\n\r xxx} , qq{abc123 xxx} ],
);
;;
note 'special case';
is CollapseWhitespace(), '', 'no arguments';
;;
note 'general cases';
VECTOR:
for my $ar_vector (@TESTS) {
if (not ref $ar_vector) {
note $ar_vector;
next VECTOR;
}
;;
my ($str, $expected) = @$ar_vector;
;;
is CollapseWhitespace($str), $expected,
pp($str) . ' -> ' . pp($expected)
;
}
;;
done_testing;
;;
exit;
;;
sub CollapseWhitespace {
my $s = shift;
return '' unless defined $s;
$s =~ s{ [\x00-\x20]+ }{ $+[0] - $-[0] == 1 ? '' : ' ' }xmsge;
return $s;
}
"
# perl version: 5.008009
# special case
ok 1 - no arguments
# general cases
ok 2 - undef -> ""
ok 3 - "" -> ""
ok 4 - " " -> ""
ok 5 - "\n" -> ""
ok 6 - "\n\t" -> " "
ok 7 - "\n\t\0" -> " "
ok 8 - "\n\t \0" -> " "
ok 9 - "\n\t abc 123 xxx\n" -> " abc123 xxx"
ok 10 - "\nabc 123\a\b\fxxx\n\t " -> "abc123 xxx "
ok 11 - "abc 123\n\r xxx" -> "abc123 xxx"
1..11
ok 12 - no warnings
1..12
If you have Perl version 5.14+, a slightly conciserer variation is:
sub CollapseWhitespace {
my $s = shift;
return defined $s
? $s =~ s{ [\x00-\x20]+ }{ $+[0] - $-[0] == 1 ? '' : ' ' }xmsger
: ''
;
}
See the s/// /r modifier in perlop. I leave it to you to Benchmark whether the s///e version is actually faster than the for-loop version.
Give a man a fish: <%-{-{-{-<
|