匹配单个字符串中重复单词的MySQL regexp模式

k97glaaz  于 2022-12-24  发布在  Mysql
关注(0)|答案(2)|浏览(154)

有人能帮我解决MySQL和REGEXP的问题吗?
我正在清理包含车辆清单的MySQL表。该表有几百万行。我正在尝试提出一个正则表达式模式,该模式将在每个单元格中查找重复的单词,并将其中一个单词替换为空格字符,以保留其他单词。下面是我的表的一个示例。该表中有许多列,但我只包含了几列用于演示目的。

如果您注意到,MAKE和MODEL这两列包含重复的单词(即“福特FORD”、“TOYOTA TOYOTA”等)。这个表格是从一个以前需要手工维护的旧Excel文件中加载的,正如你所看到的,数据非常脏。我正在尝试尽可能多地进行清理以使数据标准化。我只想保留每个重复单词的一个副本,删除重复项(即“福特”、“丰田”、“日产”等)。
我能够部分地解决这个问题(见下面的代码):

update t_inventory
set make = trim(regexp_replace(make, '(\\([A-Za-z]+\\))', ' '))
where make regexp '^([A-Za-z]+)([^a-zA-Z0-9]+)(\\([A-Za-z]+\\))'
    and mid(make, 1, instr(make, '(') - 2) = 
        mid(make, instr(make, '(') + 1, instr(make, ')') - instr(make, '(') - 1);

上面的代码解决了像“福特(FORD)”或“TOYOTA(TOYOTA)”这样的值的问题,其中第一个单词是展开的,第二个单词在括号内,没有其他前导或尾随字符。但是当我有一个像“MAKE NISSAN(NISSAN)”这样的字符串时,上面的代码就不起作用了。它会用空格替换单词NISSAN,只留下单词MAKE。
有没有什么方法可以编写一个REGEXP模式来删除所有重复的单词,只保留一个?我甚至不关心是否保留括号。我可以很容易地在以后清除它们。
你可能会问为什么不找出所有可能的垃圾,创建一个字典,然后编写一个过程来过滤掉它。是的,如果表有几百到几千行,那就太理想了。但是我的表有几百万行。正如我上面提到的,这些数据是从手工维护了20多年的Excel文件中迁移过来的。很难想象这些数据有多脏。你在上面的图表中看到的是它所能得到的最简单的东西。如果它不是那么复杂,我就不会寻求帮助了。
我真的很感谢你的帮助。先谢谢你!

h22fl7wq

h22fl7wq1#

脏数据通常过于混乱,无法在单个UPDATE中修复。
回答:使用多个UPDATE!

UPDATE t_inventory
SET make = TRIM(LEADING 'MAKE' FROM make);

UPDATE t_inventory
SET make = REPLACE(make, 'FORD (FORD)', 'FORD');

UPDATE t_inventory
SET make = REPLACE(make, 'NISSAN (NISSAN)', 'NISSAN');

UPDATE t_inventory
SET make = REPLACE(make, 'HONDA (HONDA)', 'HONDA');

...and so on...

每一个这样的编辑都非常容易编写。
现在您可能会问是否也可以在同一UPDATE中更改NISSAN (NISSAN
你还在考虑合并编辑!别这样。做多个编辑就行了。

UPDATE t_inventory
SET make = REPLACE(make, 'NISSAN (NISSAN', 'NISSAN');

执行多个编辑确实需要更长的时间。我知道你说你的表有数百万行。但是如果你和开发一种巧妙的组合编辑的方法所花费的时间相比,这可能是一场浪费。此外,计算机擅长执行数百万行的更改。你只需要等待它完成。

olmpazwi

olmpazwi2#

mysql> SELECT REGEXP_REPLACE("FORD (FORD)", '\\b(\\w+)\\b(.*)\\b(\\1)\\b(.*)$', '$1$2$4');
+-----------------------------------------------------------------------------+
| REGEXP_REPLACE("FORD (FORD)", '\\b(\\w+)\\b(.*)\\b(\\1)\\b(.*)$', '$1$2$4') |
+-----------------------------------------------------------------------------+
| FORD ()                                                                     |
+-----------------------------------------------------------------------------+

使用版本8.0.31;另一个版本可以具有不同的语法。
请注意,替换操作在没有“FORD”的第二个副本(即$3)的情况下重新生成了字符串。
解释一些事情:

\\b  -- word boundary (start or end)
(...)  -- capture what the insides matched into $1, $2, etc
\\w+  -- any string of letters
.*  -- a string of anything ('greedy' version)
\\1  -- match what the first (1) "(...)" matched
$  -- anchored at the end  (Probably unnecessary)

在更换侧:

$n  -- the nth (...) matched

3辆日产的例子比较混乱,.*很可能在第二个副本中被发送,.*?是“非贪婪的”;取代了第二辆日产

+-----------------------------------------------------------------------------------------------------------------------+
| REGEXP_REPLACE("NISSAN ALTIMA (NISSAN WHITE 2019 ) (NISSAN WHITE 2019",
         '\\b(\\w+)\\b(.*)\\b(\\1)\\b(.*)$', '$1$2$4') |
+-----------------------------------------------------------------------------------------------------------------------+
| NISSAN ALTIMA (NISSAN WHITE 2019 ) ( WHITE 2019                                                                       |
+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

+------------------------------------------------------------------------------------------------------------------------+
| REGEXP_REPLACE("NISSAN ALTIMA (NISSAN WHITE 2019 ) (NISSAN WHITE 2019",
         '\\b(\\w+)\\b(.*?)\\b(\\1)\\b(.*)$', '$1$2$4') |
+------------------------------------------------------------------------------------------------------------------------+
| NISSAN ALTIMA ( WHITE 2019 ) (NISSAN WHITE 2019                                                                        |
+------------------------------------------------------------------------------------------------------------------------+

计划A:一种方法是运行两个UPDATE,一个处理2个副本的行,另一个处理3个副本的行。
计划B:或者,使用某种循环机制,这可以通过存储过程和一些不同的函数来实现,比如SUBSTRING_INDEX()
计划C:第三个(可以说是最好的)是将数据拉到应用程序中,该应用程序可能具有更好的字符串和正则表达式处理功能。

相关问题