在我开始根据@SteveChambers 的回答实施我自己的查询后,我发现每个结果行只发生一次替换。例如,给定OP提到的表记录,这个查询:
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|$)');
将返回不同的 3 行结果:
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?
请注意,每一行只替换了一个单词。
经过一番讨论,我们得出结论,需要递归。我设法通过以下查询在没有过程或函数的情况下实现了这一点:
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;
此查询递归地替换原始字符串中的每个单词,累积替换。它使用索引 ( @i
) 对行进行编号。最后,它只返回最后一个结果(更大的索引),其中包含所有累积替换。
如果没有进行替换,它使用LEFT JOIN
组合 withIFNULL
返回原始字符串。