Regex to clean text in preparation for word count in PHP
Do it in two steps. First replace all the stuff you deem to be "junk" with spaces, then collapse the spaces and hyphens down to a single space. You can express this with a reduce through a series of patterns that collapse to a space.

Some output from a play in Boris.

[7] boris&gt; function clean($input) {
[7]     *&gt;   $patterns = array(
[7]     *&gt;     '/[^\w\r\n -]/',
[7]     *&gt;     '/[\r\n -]{2,}/'
[7]     *&gt;   );
[7]     *&gt;   return array_reduce(
[7]     *&gt;     $patterns,
[7]     *&gt;     function($text, $re) { return preg_replace($re, ' ', $text); },
[7]     *&gt;     $input
[7]     *&gt;   );
[7]     *&gt; }
[8] boris&gt; clean('abc def &amp;% f');
// 'abc def f'
[9] boris&gt; clean('abc-def &amp;% f');
// 'abc-def f'
[10] boris&gt; clean('abc-def-&amp;%-f');
// 'abc-def f