AS, уже, сказал, я скорее поймаю исключение, но использование XmlParserContext, Вы могли попытаться проанализировать "вручную" и прервать любую аномалию; однако, если Вы не анализируете 100 фрагментов XML в секунду, почему, не ловя исключение?
Я считаю, что это просто из-за порядка, в котором вы помещаете символы в массив. Попробуйте следующее:
$regex_chars = array('\\' , '[' , '^', '$' , '.' , '|' ,
'?' , '*' , '+' , '(' , ')');
$regex_chars_escaped = array( '\\\\ ' ,'\[ ', '\^ ', '\& ' ,
'\. ' , '\| ' , '\? ' , '\* ' , '\+ ' , '\( ' , '\)');
И вы должны получить ожидаемый результат. Проверьте раздел 'потенциальных ошибок' в спецификации функции str_replace