如何在MySQL数据库中查找和替换文本中的单词?

时间:2011-01-28 14:26:11

标签: php mysql database

A有一句话:

“如何在mysql数据库中查找和替换文本中的单词?”

和MySQL表格一样,带有3列id,word和replaceWord。 我在数据库中有超过4000个单词。

表:

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

结果:

“如何在 MySQL 数据库中找到并替换句子中的字母?”

我知道如何在没有数据库的情况下这样做,但我需要数据库。

 <?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);
?>

7 个答案:

答案 0 :(得分:3)

MySQL 8 +

使用REGEXP_REPLACE函数可以很容易地完成此操作:

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

请参见this dbfiddle demo

说明:\W是非单词字符的正则表达式语法(因此,必须对反斜杠进行转义,\\W)。或者,^照顾文本的开头,$照顾文本的结尾。 $1$2将带括号的捕获组中的这些字符放回替换文本中。

MySQL 8之前的版本

如果您被迫使用MySQL的早期版本,这会非常棘手,但使用自定义的书面正则表达式替换器在技术上仍然可行-有关详细信息,请参见this answer


MariaDB 10.0.5 +

正如Paul Spiegel在评论中指出的那样,支持REGEXP_REPLACE的MariaDB版本的唯一区别是使用\\1\\2而不是$1和{{ 1}}来识别捕获组:

$2

请参见this dbfiddle demo

答案 1 :(得分:2)

update YourTable, Words
    set YourTable.YourColumn = replace(YourTable.YourColumn, Words.word, Words.replaceWord)

答案 2 :(得分:1)

//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);

如果你还需要preg_replace: 您必须将列isPattern添加到表中,然后才能执行此操作:

//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);

答案 3 :(得分:0)

select REPLACE(fieldOrString, SearchString, ReplaceString) from table

答案 4 :(得分:0)

在可伸缩性方面,这是一个糟糕的想法:你可以逐字逐句地迭代句子,并在每一个上查询单词在'word'中的位置。如果确实存在(返回数据),则用'replaceWord'

中的内容替换

编辑:不完全基于数据库,但比当前版本更多。

答案 5 :(得分:0)

开始基于answer by @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 JOINIFNULL结合使用以返回原始字符串。

答案 6 :(得分:0)

$ tablesarray包含要在其中搜索任何单词或字母的列数组

$ PDO数据库连接

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="ss_menu">
  <div class="ss_button">Einsteiger</div>
  <div class="ss_content">
    <p>Test1</p>
  </div>
  <div class="ss_button">Mittelklasse</div>
  <div class="ss_content" style='display:block;'>
    <p>Test2</p>
  </div>
  <div class="ss_button">High-End</div>
  <div class="ss_content">
    <p>Test3</p>
  </div>

</div>