3

I have a sentence:

"How to find and replace word in text from mysql database?"

And MySQL table words, with to 3 column id, word and replaceWord. I have more than 4000 words in databese.

Table:

id     word     replaceWord
 1     text     sentence
 2     word     letter
 3     mysql    MySQL
 4     ..       ...
 5     ..       ...
 6     ..       ...

Result:

"How to find and replace letter in sentence from MySQL database?"

I know how to do this without database, but i need database.

 <?php
$text="How to find and replace word in text from mysql database?";
$replaceWord=array(  "text" => "sentence", "word" => "letter", "mysql" => "MySQL");
echo strtr($tekst, $replaceWord);
?>
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Pelish8
  • 109
  • 2
  • 9

7 Answers7

4

MySQL 8+

Can use the REGEXP_REPLACE function:

SELECT REGEXP_REPLACE(the_text,
                      CONCAT('(^|\\W)', text_to_find, '(\\W|$)'),
                      CONCAT('$1', replacement_text, '$2')) AS replaced_text
FROM the_table;

See this dbfiddle demo.

Explanation: \W is a regular expression syntax for a non-word character (the backslash needs to be escaped hence \\W). Alternatively, ^ caters for the very start of the text and $ the very end of the text. $1 and $2 put these characters from the parenthesized capturing groups back into the replacement text.

MySQL versions prior to 8

If you are forced to use an earlier version of MySQL it is quite a lot trickier but still technically possible using a custom written regular expression replacer - see this answer for details.


MariaDB 10.0.5+

As pointed out by Paul Spiegel in the comments, the only difference in MariaDB versions supporting REGEXP_REPLACE is the use of \\1 and \\2 instead of $1 and $2 to identify the capturing groups:

SELECT REGEXP_REPLACE(the_text,
                      CONCAT('(^|\\W)', text_to_find, '(\\W|$)'),
                      CONCAT('\\1', replacement_text, '\\2')) AS replaced_text
FROM the_table;

See this dbfiddle demo.

Steve Chambers
  • 37,270
  • 24
  • 156
  • 208
  • 1
    Fortunately, I'm running MariaDB 10.3.18 and it does support [`REGEXP_REPLACE`](https://mariadb.com/kb/en/library/regexp_replace/). I'll give this solution a try and let you know how it goes. – Gustavo Straube Oct 30 '19 at 17:00
  • 1
    @GustavoStraube - Note that in MariaDB you have to use `\\1` and `\\2` instead of `$1` and `$2`. – Paul Spiegel Oct 31 '19 at 10:04
  • Thanks @PaulSpiegel, have now added a section for MariaDB to the answer. – Steve Chambers Oct 31 '19 at 12:07
  • 1
    @SteveChambers I still have some questions on this solution. Could you join the following chat room? https://chat.stackoverflow.com/rooms/201727/discussion-on-how-to-find-and-replace-whole-words-in-a-mysql-text-field – Gustavo Straube Nov 01 '19 at 16:19
3
update YourTable, Words
    set YourTable.YourColumn = replace(YourTable.YourColumn, Words.word, Words.replaceWord)
Joe Stefanelli
  • 132,803
  • 19
  • 237
  • 235
1
select REPLACE(fieldOrString, SearchString, ReplaceString) from table
dmcnelis
  • 2,913
  • 1
  • 19
  • 28
0

Here's a terrible idea in terms of scalability: you could just iterate over the sentence word by word, and on each one do a query for where the word exists in 'word'. If it does exist (returns data) then do a replace with the content from 'replaceWord'

EDIT: Not totally database based, but more so than your current version.

josh.trow
  • 4,861
  • 20
  • 31
0
//load all replacements
$result = mysql_query("SELECT * FROM YourTableNameHere");
//replace all words
$words = array();
$replacewords =array();
while ($row = mysql_fetch_assoc($result)) {
    $words[] = $row['word'];
    $replacewords[] = $row['replaceword'];
}
$text = str_replace($words,$replacewords);

If you need preg_replace as well: You must add the column isPattern to your table, then you can do this:

//load all replacements
$result = mysql_query("SELECT * FROM YourTableNameHere");
//replace all words
$words = array();
$replacewords = array();
$preg_words = array();
$preg_replacewords = array();
while ($row = mysql_fetch_assoc($result)) {
    if(!$row['isPattern']){        
        $words[] = $row['word'];
        $replacewords[] = $row['replaceword'];
    }
    else{
        $preg_words[] = $row['word'];
        $preg_replacewords[] = $row['replaceword'];
    }
}
$text = str_replace($words,$replacewords);
$text = $preg_replace($preg_words,$preg_replacewords);
Oliver A.
  • 2,870
  • 2
  • 19
  • 21
  • I have more than 4000 words, is there a another solution? – Pelish8 Jan 28 '11 at 14:50
  • updated it so it just needs one call of str_replae. Do you want to do this on PHP or do you want to do this with SQL? Im not sure that I did get you right ;) – Oliver A. Jan 28 '11 at 23:09
  • In PHP, thank you, but i have one problem. Script realplayer all word with last in database. So my firs sentence will look like: "How to find and replace MySQL in MySQL from MySQL database?" – Pelish8 Jan 29 '11 at 09:42
  • OK, i figured it, only add [] to the $replacewords. I have several exceptions. In my language we have a word "da li", and if i replace "dali" with "da li" then i have a problem in name of "salvatore dali"="salvatore da li". Can you help me with this and I will stop bother you?! :) Thanks again. – Pelish8 Jan 29 '11 at 10:57
  • No not really. I you exactly know the exceptions you could try searching for patterns instead o wirds (e.g any word taht is NOT"salvador" followed by "dali"), but I can hardly explain poattern search in a short answer. I will edit my post so you can use pregreplace to searh or patterns but you will have to learn how to use preg_replace for yourself. – Oliver A. Jan 29 '11 at 12:50
  • Thanks a lot. I will endeavor to learn how to use preg_replace. – Pelish8 Jan 29 '11 at 15:42
0

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.

Gustavo Straube
  • 3,744
  • 6
  • 39
  • 62
-1

$tablesarray include column array where you want to search Any word or letter

$PDO database connection

    $tablesarray['tablename1']= array('column1' ,'column2' );
    $tablesarray['tablename2']= array('column1' ,'column2' );
    
    $wordstoreplace = ['searchedwordOrLetter1'=>'replacedwordOrLetter1' , 'searchedwordOrLetter2'=>'replacedwordOrLetter2' ]
    foreach($repairkeyarray as $table => $columns){
        foreach($columns as $column){
            foreach($wordstoreplace as $searched => $replaced ){
                $PDO->query("update $table set `$column` = replace(`$column`, '$searched', '$replaced') WHERE `$column` LIKE '%$searched%';");
                @$PDO->execute();
            }
        }
    }
Akram Elhaddad
  • 194
  • 3
  • 7