Добре, намерих отговора. Очевидно трябва да избягам двойно от обратната наклонена черта в замяната. Освен това трябва да E
-префикс и двойни екраниращи обратни наклонени черти в шаблона за търсене на по-стари версии на postgres (8.3 в моя случай). Крайният код изглежда така:
regexp_replace('abc [def]', E'([\\[\\]\\(\\)\\\\\?\\|_%])', E'\\\\\\1', 'g')
Да, изглежда ужасно, но работи :)