use strict; use warnings; my (%count, $last); my $max = 0; while () { s/^ +//; s/\s+$//; s/ +/ /g; ## Remove extra spaces $_ = lc($_); ## Lowercase so not sensitive $_ = $last . $_; ## Append word piece if (m/-$/) { ## If line ends in -, remove last ($_, $last) = m/(.*?) ?(\w+)-/; ## word piece for appending } else { $last = ''; } ## Else word piece is nothing s/[^\w' ]//g; ## Remove extra punctuation s/(\w)'(\w)/$1-$2/g; ## Convert ' inside words to - s/'//g; ## Remove all remaining ' s/-/'/g; ## Convert - back to ' for (split / +/) { ## Split on space and $count{$_}++; ## process words $max = length() if length() > $max; ## Find longest word size } } print sprintf('%'.$max.'s', $_) . " => $count{$_}\n" for sort { $count{$b} <=> $count{$a} || $a cmp $b} keys %count; __DATA__ I can't be bought, and I won't be bought! My school- house is my own, my precious. One school to rule them all! This is my cant, my creed. Funky space check!