When talking about making things idiot proof a common response is "never underestimate the ingenuity of idiots."

Once again, I feel like a bit of an idiot.

It suddenly dawned on me why my preg_replace function was ignoring double quotes: WordPress uses curly or 'smart' quotes whereas I was checking for straight quotes.

🤦‍♂️

It may not be typographically correct or as aesthetically pleasing but I have, for the time being, told WordPress to only display straight quotes by using the following:

remove_filter('the_content', 'wptexturize');

Hashtags are now working as expected.