The documentation for regex-tdfa says that it doesn’t support find-and-replace, so there is no official way to do replacement. So maybe there isn’t any method other than the ways mentioned so far.
But is there really a reason to be worried about the performance cost of splitting strings? I don’t think splitting a string in Haskell requires copying. At least, it shouldn’t require copying the tail end of the string, which is what would be expensive if you’re iterating over a long text to find multiple non-overlapping matches. (Although people say that the only way to really know about performance characteristics is to run the code and measure them.)
Also, if you’re concerned about performance, have you considered using Text instead of String? Text is often said to be faster and more memory-efficient, and internally it uses indexing to make substrings, so splitting Text should be efficient too.
I’m using Text, so good to know that splitting shouldn’t be an issue.
However, maybe I can avoid this whole workaround: I am right now thinking of switching to a regex lib which directly provides replacement. I might try pcre-heavy…