After I started to implement my own query based on the answer by @SteveChambers I found the substitution happened only once per result row. For example, given the table records mentioned by the OP, this query:
SELECT
word,
replaceWord,
REGEXP_REPLACE(
'How to find and replace word in text from mysql database?',
CONCAT('(?i)(^|\\W)', word, '(\\W|$)'),
CONCAT('\\1', replaceWord, '\\2')
) AS replaced_text
FROM
words
WHERE
'How to find and replace word in text from mysql database?' REGEXP CONCAT('(?i)(^|\\W)', word, '(\\W|$)');
would return distinct 3 rows of results:
word | replaceWord | replaced_text
------+-------------+--------------
text | sentence | How to find and replace letter in text from mysql database?
word | letter | How to find and replace word in sentence from mysql database?
mysql | MySQL | How to find and replace word in text from MySQL database?
Notice each row has only one word replaced.
After some discussion, we got to the conclusion that recursion was required. I managed to achieve that without a procedure or function with the following query:
SELECT
(@i := @i + 1) AS i,
@tmp := IFNULL(
REGEXP_REPLACE(
@tmp,
CONCAT('(?i)(^|\\W)', word, '(\\W|$)'),
CONCAT('\\1', replaceWord, '\\2')
),
@tmp
) AS replaced_text
FROM
(
SELECT
@tmp := 'How to find and replace word in text from mysql database?',
@i := 0
) x
LEFT JOIN
words
ON
@tmp REGEXP CONCAT('(?i)(^|\\W)', word, '(\\W|$)')
ORDER BY i DESC
LIMIT 1;
This query recursively replaces each word in the original string, accumulating the replacements. It uses an index (@i
) to number the rows. Finally, it returns only the last result (greater index), which contains all accumulate replacements.
It uses a LEFT JOIN
combined with IFNULL
to return the original string in case no substitution is made.