replace() function produce an empty string if the string to be replaced starts with a "+" character.
this search with replace() works:
| makeresults
| eval message = "This is mark1 replacement mark2", ph2="different"
| rex field=message "mark1 (?<ph1>[^/s]*) mark2"
| eval message2 = replace(message, ph1, ph2)
| table message, message2, ph1, ph2
this one will produce an empty message2:
| makeresults
| eval message = "This is mark1 +replacement mark2", ph2="different"
| rex field=message "mark1 (?<ph1>[^/s]*) mark2"
| eval message2 = replace(message, ph1, ph2)
| table message, message2, ph1, ph2
The replace function treats the string to be replaced as a regex - "+" is a special character in regex and because it isn't preceded by anything, this makes the regex invalid, hence, it does perform as expected.
the function should have ways to escape the special characters. As you can see above, the extraction rex has no problem handling it.
The extraction works because the extracted string is not processed as a regex (until you put it in the replace function).
You could try something like this
| rex mode=sed field=ph1 "s/([\+\\\*\{\}\[\]\.\(\)\|\?])/#\#\1/g"
| rex mode=sed field=ph1 "s/#//g"
| eval message2 = replace(message, ph1, ph2)