replace string with a callback