MySQL 正则表达式(Regexp)
⚡ 智能摘要
MySQL 正则表达式 (REGEXP) 将列值与通配符无法表达的灵活模式进行匹配。本文解释了 REGEXP 语法、RLIKE 同义词、所有支持的元字符、针对 myflixdb 数据库的更正查询示例以及新增的正则表达式函数。 MySQL 8.0.

是什么 MySQL 正则表达式?
MySQL 正则表达式 它可以帮助您搜索符合复杂条件的数据。正则表达式是一种描述您要查找的值的形状的模式,而不是值本身。
如果您已经与……合作过 MySQL 通配符你可能会问,既然 LIKE 函数也能得到类似的结果,为什么还要学习正则表达式呢?答案在于正则表达式的表达能力:通配符只能提供两个符号,而正则表达式可以在一个模式中描述字符范围、替代字符、重复字符以及单词位置。
既然目的已经明确,下一节将介绍您将在每个 REGEXP 查询中使用的语法。
正则表达式的基本语法
正则表达式的基本语法如下。
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
位置:
- “SELECT语句” 是标准 选择语句.
- “WHERE 字段名称” 是执行正则表达式的列的名称。
- “REGEXP‘模式’” — REGEXP 是正则表达式运算符,“pattern”表示要匹配的模式。 RLIKE 是一个意念波· REGEXP 的同义词 并且返回相同的结果。为了避免与 LIKE 运算符混淆,最好使用正则表达式。
现在让我们来看一个实际例子。
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
上述查询会搜索所有包含单词“code”的电影标题。“code”出现在标题的开头、中间还是结尾都无关紧要。只要标题包含该模式,就会返回该行结果。
将值的开头与字符列表进行匹配
假设我们想要查找片名以 a、b、c 或 d 开头,后跟任意数量其他字符的电影。我们可以将字符列表与插入符号元字符结合使用来实现这一目标。
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
在以下位置执行上述脚本 MySQL 工作台 与 myflixdb 数据库进行比对,得到以下结果。
| 电影 ID | 标题 | 导向器 | 发行年份 | 类别编号 |
|---|---|---|---|---|
| 4 | Code 黑 | 埃德加·吉姆斯 | 2010 | 无 |
| 5 | 爸爸的小女孩 | 无 | 2007 | 8 |
| 6 | 天使与魔鬼 | 无 | 2007 | 6 |
| 7 | 达芬奇 Code | 无 | 2007 | 6 |
在模式“^[abcd]”中,插入符号 (^) 要求匹配从值的开头开始,字符列表 [abcd] 只接受首字母为 a、b、c 或 d 的字符。在默认排序规则下,比较不区分大小写,这就是为什么“Code 返回名称“Black”。
排除字符列表为否定字符的字符
现在让我们修改脚本,对字符列表取反,看看会返回哪些行。
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
在以下位置执行上述脚本 MySQL 使用 Workbench 对 myflixdb 数据库进行测试,得到以下结果。
| 电影 ID | 标题 | 导向器 | 发行年份 | 类别编号 |
|---|---|---|---|---|
| 1 | 加勒比海盗4 | 罗伯·马歇尔 | 2011 | 1 |
| 2 | 忘掉莎拉·马歇尔 | 尼古拉斯·斯托勒 | 2008 | 2 |
| 3 | X-战警 | 2008 | ||
| 9 | Honey moonERS | 约翰舒尔茨 | 2005 | 8 |
| 16 | 67% 有罪 | 2012 | ||
| 17 | 大独裁者 | 查理·查普利 | 1920 | 7 |
| 18 | 样片 | 匿名 | 8 | |
| 19 | 电影3 | 约翰·布朗 | 1920 | 8 |
在字符列表中,插入符号的含义发生了变化:'^[^abcd]' 仍然将匹配项锚定在开头,而 [^abcd] 现在排除所有以所包含字符之一开头的标题。
这两个例子仅使用了锚点和字符列表。下一节将介绍完整的元字符集。
正则表达式元字符
以上示例展示了最简单的正则表达式形式。元字符允许您对模式搜索进行微调:它们可以表示重复、替代、范围和位置。下表列出了所有支持的元字符。 MySQL 正则表达式运算符,并为每个运算符提供一个修正后的示例。
| 夏亚 | 描述 | 例如: | |
|---|---|---|---|
| * | 此 星号(*) 匹配零 (0) 个或多个实例 单个字符 在它之前。 | SELECT * FROM 电影 WHERE 标题 REGEXP 'da*'; 匹配字母“d”后跟零个或多个字母“a”,例如达芬奇 Code 《爸爸的小女孩》也符合条件。当字母“a”必须出现时,请使用“da+”。 | |
| + | 此 加号(+) 与前面的一个或多个字符匹配。 | 从 `电影` 中选择 * 其中 `标题` REGEXP'mon+'; 列出所有包含“mon”后跟一个或多个“n”字符的电影。例如,《天使与魔鬼》。 | |
| ? | 此 问号(?) 匹配零个(0)或一个与其前面的字符。 | 从 `categories` 中选择 *,其中 `category_name` REGEXP'com?'; 匹配“co”,可选配“m”。例如,喜剧和浪漫喜剧。 | |
| . | 此 点 (.) 匹配除换行符以外的任何单个字符。 | 从电影中选择*其中`year_released` REGEXP'200。'; 列出所有以“200”开头,后跟任意单个字母的年份上映的电影。例如,2005、2007、2008。 | |
| [ABC] | 此 角色列表 [abc] 匹配所包含的任意一个字符。 | 从 `电影` 中选择 * 其中 `标题` REGEXP '[vwxyz]'; 列出所有包含“vwxyz”中任意单个角色的电影。例如,《X战警》和《达芬奇》。 Code. | |
| [^abc] | 此 否定列表 [^abc] 匹配除括号内字符以外的任何字符。 | 从 `电影` 中选择 * 其中 `标题` REGEXP '^[^vwxyz]'; 列出所有片名不以“vwxyz”中的字符开头的电影。 | |
| [AZ] | 此 范围 [AZ] 匹配任何大写字母。 | 从 `成员` 中选择 * 其中 `邮政地址` REGEXP '[AZ]'; 列出所有邮政地址包含 A 到 Z 之间字母的会员。例如,会员编号为 1 的 Janet Jones。 | |
| [az] | 此 范围 [az] 匹配任何小写字母。 | 从 `成员` 中选择 * 其中 `邮政地址` REGEXP '[az]'; 列出邮政地址中包含字母 a 到 z 的所有成员。请注意,默认排序规则不区分大小写,因此该范围也包含大写字母。 | |
| [0-9] | 此 范围 [0-9] 匹配 0 到 9 之间的任意数字。 | SELECT * FROM `members` WHERE `contact_number` REGEXP '[0-9]'; 列出所有联系电话中至少包含一位数字的成员。例如,Robert Phil。 | |
| ^ | 此 插入符号 (^) 将匹配项锚定到值的开头。 | 从 `电影` 中选择 * 其中 `标题` REGEXP '^[cd]'; 列出所有片名以“c”或“d”开头的电影。例如: Code 给《布莱克》、《爸爸的小女孩》和《达芬奇》起名字 Code. | |
| $ | 此 美元符号 ($) 将匹配项锚定到值的末尾。 | SELECT * FROM `movies` WHERE `title` REGEXP 'code$'; 列出所有片名以“code”结尾的电影。例如,《达芬奇》 Code. | |
| | | 此 竖线 (|) 隔离替代方案。 | 从 `电影` 中选择 * 其中 `标题` REGEXP '^[cd]|^[u]'; 列出所有片名以“c”、“d”或“u”开头的电影。例如: Code 名字:布莱克,达芬奇 Code以及《黑夜传说》—— AwakenING。 | |
| \b | 此 单词边界 (\b) 匹配单词的开头或结尾。它取代了旧的 [[:<:]] 和 [[:>:]] 标记,这些标记 MySQL 8.0 已移除。 | SELECT * FROM `movies` WHERE `title` REGEXP '\\bfor'; 列出所有以“for”开头的电影。例如,《忘掉莎拉·马歇尔》。 MySQL 5.7 等效模式为'[[:<:]]for'。 | |
| [[:班级:]] | 此 字符类 匹配一组指定的字符:[[:alpha:]] 代表字母,[[:space:]] 代表空格,[[:punct:]] 代表标点符号,[[:upper:]] 代表大写字母。注意…… 翻番 方括号。 | SELECT * FROM `movies` WHERE `title` REGEXP '^[[:alpha:][:space:]]+$'; 列出所有片名仅包含字母和空格的电影。例如,《忘掉莎拉·马歇尔》(Forgetting Sarah Marshal),而《加勒比海盗4》(Pirates of the Caribean 4)由于片名中包含数字而被排除在外。 | |
反斜杠 (\) 是转义字符。因为 MySQL 首先解析字符串,然后解析模式;字面反斜杠必须写成双反斜杠(\\)在正则表达式模式中。
⚠️ 版本警告: MySQL 8.0.4 版本用 ICU 库替换了旧的正则表达式引擎。该版本移除了词标记 [[:<:]] 和 [[:>:]],因此从旧版本复制的模式会报错,提示“语法错误”。 MySQL 8.0. 请改用 \b。
既然每个元字符都已定义,那么接下来就出现了一个合理的问题:何时应该使用正则表达式 (REGEXP) 来代替更简单的 LIKE 运算符?
正则表达式 (REGEXP) 与 LIKE:你应该使用哪一个?
这两个运算符都按模式过滤行,但它们解决的问题不同。LIKE 运算符仅识别两个符号,而 REGEXP 运算符则识别上面所示的完整元字符集。这种强大的功能是有代价的,因此选择它是一种权衡,而不是一种偏好。
| 标准 | 样 | REGEXP |
|---|---|---|
| 图案符号 | % 和 _ 仅 | Anchors、范围、交替、量词、字符类 |
| 典型用途 | 前缀、后缀和“包含”搜索 | 验证、多种替代方案、位置感知匹配 |
| 索引使用情况 | 当图案不以 % 开头时,这种情况可能发生。 | 从不使用索引 |
| 返回值 | 对或错 | 返回值为 1 或 0,当任一操作数为 NULL 时,返回值为 NULL。 |
对于简单的匹配,请选择 LIKE 函数,因为它易于阅读且仍然可以使用索引。当单个模式需要同时表达多个规则时,例如“以 c 或 d 开头并以数字结尾”,请选择 REGEXP 函数。对于大型表,首先使用索引条件缩小行范围,然后将 REGEXP 应用于缩小后的集合。
MySQL 8.0 正则表达式函数
正则表达式运算符只回答一个问题:该值是否与模式匹配? MySQL 8.0 版本新增了四项功能,进一步扩展了定位功能,例如……tract,并重写匹配的文本。每个函数都接受一个可选的 match_type 参数,其中 'c' 强制区分大小写进行比较,'i' 强制不区分大小写进行比较。
- REGEXP_LIKE(expr, pattern) 当值与模式匹配时返回 1。它是正则表达式运算符的函数形式,`match_type` 参数明确区分大小写。
- REGEXP_INSTR(expr, pattern) 返回匹配项中第一个字符的位置,如果未找到匹配项,则返回 0。
- REGEXP_SUBSTR(expr, pattern) 返回匹配的子字符串本身,这对于从较长的文本值中提取年份、代码或数字非常有用。
- REGEXP_REPLACE(表达式, 模式, 替换) 返回替换所有匹配项后的值,因此它可以清理内部数据。 SQL UPDATE 查询.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
上述查询返回所有包含数字的电影标题,以及这些数字本身。 MySQL 5.7 这些功能不可用,因此正则表达式运算符仍然是唯一的选择。
