in reply to Truncate string to limited length, throwing away unimportant characters first.
#!/usr/bin/perl use strict; use warnings; my $max_len = 6; for my $i ( " ab ", " ab ", " abc ", " abcd ", " abcde ", " abcdef ", " abcdefg " ) { my $o = $i; while (length $o > $max_len) { next if $o =~ s/\s$//; next if $o =~ s/^\s//; $o =~ s/.$//; } printf "%-15s%s", qq("$i"), qq( => "$o"\n); }
If this is running the regular expression engine a bit much, you can refactor into three while loops, though I think this is less clear for casual inspection:
#!/usr/bin/perl use strict; use warnings; my $max_len = 6; for my $i ( " ab ", " ab ", " abc ", " abcd ", " abcde ", " abcdef ", " abcdefg " ) { my $o = $i; while (length $o > $max_len and $o =~ s/\s$//){} while (length $o > $max_len and $o =~ s/^\s//){} while (length $o > $max_len and $o =~ s/.$//){} printf "%-15s%s", qq("$i"), qq( => "$o"\n); }
Update: Or better yet, avoid the looping with quantifiers:
#!/usr/bin/perl use strict; use warnings; my $max_len = 6; my $calc_code = sub{ return length($_[0]) > $max_len ? length($_[0]) - $max_len : 0; }; for my $i ( " ab ", " ab ", " abc ", " abcd ", " abcde ", " abcdef ", " abcdefg " ) { my $o = $i; my $extra; $o =~ s/\s{0,$extra}$// if $extra = $calc_code->($o); $o =~ s/^\s{0,$extra}// if $extra = $calc_code->($o); $o =~ s/.{$extra}$// if $extra = $calc_code->($o); printf "%-15s%s", qq("$i"), qq( => "$o"\n); }
|
|---|