Случайно обнаружилось что функция preg_match() тупит если дать ей строку больше чем 100 тыщ символов. решается добавлением строки ini_set("pcre.backtrack_limit",500000);
//(значение поменять по необходимости)
Ещё есть подозрение что у htmlspecialchars с этим не всё гладко... но в общем непонятно... с добавленной строкой работает и эта функция