You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL中使用REGEXP查询customer表custom_id字段的匹配问题

解决JSON字段的正则匹配问题

嘿,我来帮你搞定这个查询问题~首先得说,你之前的正则写法有问题,因为方括号[]在正则表达式里是特殊字符(用来定义字符集合),直接写的话会被正则引擎解析成别的意思,而不是你想要的JSON里的方括号,所以必须转义才行。另外,针对动态条件的需求,我们可以构造一个灵活的正则表达式来实现。

用REGEXP实现的解决方案

首先,我们需要构造一个能匹配以下逻辑的正则:

  1. 找到"20"这个键
  2. 匹配该键对应的数组(转义方括号)
  3. 数组中包含82、83、84中的任意一个(注意这些值有的带引号,有的不带,要兼容两种情况)

对应的SQL语句如下:

SELECT * FROM `customer` 
WHERE `custom_id` REGEXP '"20":\\[(?:.*?)(\"?82\"?|\"?83\"?|\"?84\"?)(?:.*?)\\]';

正则部分的细节解释:

  • \"20\"::精确匹配键"20"和后面的冒号
  • \\[:转义方括号,匹配JSON数组的左括号(因为MySQL里正则转义需要双反斜杠)
  • (?:.*?):非贪婪匹配任意字符(非捕获组,避免额外捕获内容),用来跳过数组开头到目标值之间的内容
  • (\"?82\"?|\"?83\"?|\"?84\"?):匹配任意一个目标值,\"?表示引号是可选的(兼容JSON里的字符串和数字类型值),|表示“或”的逻辑
  • (?:.*?)\\]:继续非贪婪匹配到数组的右括号\\](同样需要转义)

动态条件的处理

如果82、83、84是动态变化的,你可以在应用层(比如PHP、Python等)把这些值拼接成正则的分支部分。举个例子,假设你有一个值列表$targetValues = [82,83,84],可以生成这样的片段:

\"?".implode("\"?|\"?", $targetValues)."\"?

然后把这个片段插入到上面的正则中,就能动态生成符合条件的正则表达式了。

更可靠的替代方案:用MySQL JSON函数

其实如果你的MySQL版本是5.7及以上,更推荐用专门的JSON函数来处理,比正则表达式更准确,不容易出现误匹配的情况。比如用JSON_CONTAINS_PATH判断键是否存在,用JSON_CONTAINS判断数组是否包含目标值:

SELECT * FROM `customer` 
-- 先判断"20"这个键是否存在
WHERE JSON_CONTAINS_PATH(`custom_id`, 'one', '$.20') 
AND (
    -- 匹配带引号的字符串值"82"
    JSON_CONTAINS(JSON_EXTRACT(`custom_id`, '$.20'), '"82"') 
    OR JSON_CONTAINS(JSON_EXTRACT(`custom_id`, '$.20'), '"83"') 
    -- 匹配不带引号的数字值84
    OR JSON_CONTAINS(JSON_EXTRACT(`custom_id`, '$.20'), '84')
);

这个方法的优势是直接针对JSON结构解析,不会像正则那样可能匹配到其他无关的内容(比如其他键里的相似数值),稳定性更高。

内容的提问来源于stack exchange,提问作者sakirow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:17:09