Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

14.8.2 正则表达式

表 14.14 正则表达式函数和操作符

Name Description
NOT REGEXP REGEXP 的否定
REGEXP 字符串是否匹配正则表达式
REGEXP_INSTR() 正则表达式匹配的子串的起始索引
REGEXP_LIKE() 字符串是否匹配正则表达式
REGEXP_REPLACE() 用正则表达式替换子串
REGEXP_SUBSTR() 返回匹配正则表达式的子串
RLIKE 字符串是否匹配正则表达式

正则表达式是一种指定复杂搜索模式的强大方式。本节讨论了用于正则表达式匹配和操作符的函数,并通过示例说明了一些特殊字符和构造可以用于正则表达式操作。另见 第 5.3.4.7 节,“模式匹配”

MySQL 使用 International Components for Unicode (ICU) 实现正则表达式支持,提供了完整的 Unicode 支持和多字节安全。

使用任何 MySQL 正则表达式函数的二进制字符串将被拒绝,错误代码为 ER_CHARACTER_SET_MISMATCH

正则表达式函数和操作符描述

  • expr NOT REGEXP pat, expr NOT RLIKE pat

    这与 NOT (expr REGEXP pat) 相同。

  • expr REGEXP pat, expr RLIKE pat

    如果字符串 expr 匹配正则表达式模式 pat,则返回 1,否则返回 0。如果 exprpatNULL,则返回值为 NULL

    REGEXPRLIKEREGEXP_LIKE() 的同义词。

    有关匹配如何发生的更多信息,请参见 REGEXP_LIKE() 的描述。

    mysql> SELECT 'Michael!' REGEXP '.*';
    +------------------------+
    | 'Michael!' REGEXP '.*' |
    +------------------------+
    |                      1 |
    +------------------------+
    mysql> SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
    +---------------------------------------+
    | 'new*\n*line' REGEXP 'new\\*.\\*line' |
    +---------------------------------------+
    |                                     0 |
    +---------------------------------------+
    mysql> SELECT 'a' REGEXP '^[a-d]';
    +---------------------+
    | 'a' REGEXP '^[a-d]' |
    +---------------------+
    |                   1 |
    +---------------------+
  • REGEXP_INSTR(expr, pat[, pos[, occurrence[, return_option[, match_type]]]])

    返回字符串 expr 中与模式 pat 匹配的子串的起始索引,若无匹配则返回 0。如果 exprpatNULL,则返回值为 NULL。字符索引从 1 开始。

    REGEXP_INSTR() 接受以下可选参数:

    • pos:在 expr 中开始搜索的位置。如果省略,默认为 1。

    • occurrence:要搜索的匹配次数。如果省略,默认为 1。

    • return_option:要返回的位置类型。如果该值为 0,REGEXP_INSTR() 返回匹配子串的第一个字符的位置。如果该值为 1,REGEXP_INSTR() 返回匹配子串后的位置。如果省略,默认为 0。

    • match_type:一个字符串,指定如何执行匹配。其含义与 REGEXP_LIKE() 中的描述相同。

    有关匹配如何发生的更多信息,请参阅 REGEXP_LIKE() 的描述。

    mysql> SELECT REGEXP_INSTR('dog cat dog', 'dog');
    +------------------------------------+
    | REGEXP_INSTR('dog cat dog', 'dog') |
    +------------------------------------+
    |                                  1 |
    +------------------------------------+
    mysql> SELECT REGEXP_INSTR('dog cat dog', 'dog', 2);
    +---------------------------------------+
    | REGEXP_INSTR('dog cat dog', 'dog', 2) |
    +---------------------------------------+
    |                                     9 |
    +---------------------------------------+
    mysql> SELECT REGEXP_INSTR('aa aaa aaaa', 'a{2}');
    +-------------------------------------+
    | REGEXP_INSTR('aa aaa aaaa', 'a{2}') |
    +-------------------------------------+
    |                                   1 |
    +-------------------------------------+
    mysql> SELECT REGEXP_INSTR('aa aaa aaaa', 'a{4}');
    +-------------------------------------+
    | REGEXP_INSTR('aa aaa aaaa', 'a{4}') |
    +-------------------------------------+
    |                                   8 |
    +-------------------------------------+
  • REGEXP_LIKE(expr, pat[, match_type])

    如果字符串 expr 匹配模式 pat,则返回 1,否则返回 0。如果 exprpatNULL,则返回值为 NULL

    模式可以是一个扩展的正则表达式,其语法在 正则表达式语法 中讨论。模式不需要是一个文字字符串。例如,它可以指定为字符串表达式或表列。

    可选的 match_type 参数是一个字符串,可能包含以下字符,指定如何执行匹配:

    • c:区分大小写的匹配。

    • i:不区分大小写的匹配。

    • m:多行模式。识别字符串中的行终止符。默认行为是仅在字符串表达式的开始和结束处匹配行终止符。

    • n. 字符匹配行终止符。默认情况下,. 匹配停止在字符串表达式的末尾。

    • u:仅 Unix 风格的行结束符。只有换行符被 .^$ 匹配运算符识别为行结束符。

    如果 match_type 中指定了相互矛盾的选项,则右侧的选项优先。

    默认情况下,正则表达式操作使用 exprpat 参数的字符集和排序规则来确定字符类型并执行比较。如果参数具有不同的字符集或排序规则,协调规则将应用,如 第 12.8.4 节“表达式中的排序规则协调” 所述。可以使用明确的排序规则指示符来更改比较行为。

    mysql> SELECT REGEXP_LIKE('CamelCase', 'CAMELCASE');
    +---------------------------------------+
    | REGEXP_LIKE('CamelCase', 'CAMELCASE') |
    +---------------------------------------+
    |                                     1 |
    +---------------------------------------+
    mysql> SELECT REGEXP_LIKE('CamelCase', 'CAMELCASE' COLLATE utf8mb4_0900_as_cs);
    +------------------------------------------------------------------+
    | REGEXP_LIKE('CamelCase', 'CAMELCASE' COLLATE utf8mb4_0900_as_cs) |
    +------------------------------------------------------------------+
    |                                                                0 |
    +------------------------------------------------------------------+

    match_type 可以指定 ci 字符来覆盖默认的大小写敏感性。例外:如果任一参数是二进制字符串,则参数将作为二进制字符串以大小写敏感方式处理,即使 match_type 包含 i 字符。

    Note

    MySQL 在字符串中使用 C escape 语法(例如,\n 代表换行符)。如果您想在 exprpat 参数中包含文字 \,则必须将其双倍。(除非启用了 NO_BACKSLASH_ESCAPES SQL 模式,在这种情况下,不使用转义字符。)

    mysql> SELECT REGEXP_LIKE('Michael!', '.*');
    +-------------------------------+
    | REGEXP_LIKE('Michael!', '.*') |
    +-------------------------------+
    |                             1 |
    +-------------------------------+
    mysql> SELECT REGEXP_LIKE('new*\n*line', 'new\\*.\\*line');
    +----------------------------------------------+
    | REGEXP_LIKE('new*\n*line', 'new\\*.\\*line') |
    +----------------------------------------------+
    |                                            0 |
    +----------------------------------------------+
    mysql> SELECT REGEXP_LIKE('a', '^[a-d]');
    +----------------------------+
    | REGEXP_LIKE('a', '^[a-d]') |
    +----------------------------+
    |                          1 |
    +----------------------------+
    mysql> SELECT REGEXP_LIKE('abc', 'ABC');
    +---------------------------+
    | REGEXP_LIKE('abc', 'ABC') |
    +---------------------------+
    |                         1 |
    +---------------------------+
    mysql> SELECT REGEXP_LIKE('abc', 'ABC', 'c');
    +--------------------------------+
    | REGEXP_LIKE('abc', 'ABC', 'c') |
    +--------------------------------+
    |                              0 |
    +--------------------------------+
  • REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])

    在字符串 expr 中用正则表达式指定的模式 pat 替换字符串 repl,并返回结果字符串。如果 exprpatreplNULL,则返回值为 NULL

    REGEXP_REPLACE() 可以带以下可选参数:

    • pos:在 expr 中开始搜索的位置。如果省略,默认为 1。

    • occurrence:要替换的匹配次数。如果省略,默认为 0(表示“替换所有匹配”)。

    • match_type:一个字符串,指定如何执行匹配。其含义与 REGEXP_LIKE() 中的相同。

    该函数返回的结果使用搜索匹配的表达式的字符集和排序规则。

    有关匹配如何发生的更多信息,请参阅 REGEXP_LIKE() 的描述。

    mysql> SELECT REGEXP_REPLACE('a b c', 'b', 'X');
    +-----------------------------------+
    | REGEXP_REPLACE('a b c', 'b', 'X') |
    +-----------------------------------+
    | a X c                             |
    +-----------------------------------+
    mysql> SELECT REGEXP_REPLACE('abc def ghi', '[a-z]+', 'X', 1, 3);
    +----------------------------------------------------+
    | REGEXP_REPLACE('abc def ghi', '[a-z]+', 'X', 1, 3) |
    +----------------------------------------------------+
    | abc def X                                          |
    +----------------------------------------------------+
  • REGEXP_SUBSTR(expr, pat[, pos[, occurrence[, match_type]]])

    返回字符串 expr 中与正则表达式指定的模式 pat 匹配的子串,如果没有匹配则返回 NULL。如果 exprpatNULL,则返回值为 NULL

    REGEXP_SUBSTR() 可以带以下可选参数:

    • pos:在 expr 中开始搜索的位置。如果省略,默认为 1。

    • occurrence:要搜索的匹配次数。如果省略,默认为 1。

    • match_type:一个字符串,指定如何执行匹配。其含义与 REGEXP_LIKE() 中的相同。

    该函数返回的结果使用搜索匹配的表达式的字符集和排序规则。

    有关匹配如何发生的更多信息,请参阅 REGEXP_LIKE() 的描述。

    mysql> SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+');
    +----------------------------------------+
    | REGEXP_SUBSTR('abc def ghi', '[a-z]+') |
    +----------------------------------------+
    | abc                                    |
    +----------------------------------------+
    mysql> SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+', 1, 3);
    +----------------------------------------------+
    | REGEXP_SUBSTR('abc def ghi', '[a-z]+', 1, 3) |
    +----------------------------------------------+
    | ghi                                          |
    +----------------------------------------------+

正则表达式语法

正则表达式描述了一组字符串。最简单的正则表达式是没有特殊字符的那个。例如,正则表达式 hello 只匹配 hello

非平凡的正则表达式使用某些特殊构造,以便匹配多个字符串。例如,正则表达式 hello|world 包含 | 选择操作符,匹配 helloworld

作为一个更复杂的示例,正则表达式 B[an]*s 匹配任何以 B 开头,以 s 结尾,并且在中间包含任意数量的 an 字符的字符串。

以下列表涵盖了一些基本的特殊字符和构造,可以在正则表达式中使用。有关 ICU 库实现正则表达式支持的完整语法,请访问 国际化组件 Unicode 网站

  • ^

    匹配字符串的开始。

    mysql> SELECT REGEXP_LIKE('fo\nfo', '^fo$');                   -> 0
    mysql> SELECT REGEXP_LIKE('fofo', '^fo');                      -> 1
  • $

    字符串的结尾。

    mysql> SELECT REGEXP_LIKE('fo\no', '^fo\no$');                 -> 1
    mysql> SELECT REGEXP_LIKE('fo\no', '^fo$');                    -> 0
  • .

    匹配任何字符(包括回车和换行,尽管要在字符串中间匹配这些,需要使用 m(多行)匹配控制字符或 (?m) 模式修饰符)。

    mysql> SELECT REGEXP_LIKE('fofo', '^f.*$');                    -> 1
    mysql> SELECT REGEXP_LIKE('fo\r\nfo', '^f.*$');                -> 0
    mysql> SELECT REGEXP_LIKE('fo\r\nfo', '^f.*$', 'm');           -> 1
    mysql> SELECT REGEXP_LIKE('fo\r\nfo', '(?m)^f.*$');           -> 1
  • a*

    匹配零个或多个 a 字符。

    mysql> SELECT REGEXP_LIKE('Ban', '^Ba*n');                     -> 1
    mysql> SELECT REGEXP_LIKE('Baaan', '^Ba*n');                   -> 1
    mysql> SELECT REGEXP_LIKE('Bn', '^Ba*n');                      -> 1
  • a+

    匹配一个或多个 a 字符。

    mysql> SELECT REGEXP_LIKE('Ban', '^Ba+n');                     -> 1
    mysql> SELECT REGEXP_LIKE('Bn', '^Ba+n');                      -> 0
  • a?

    匹配零个或一个 a 字符。

    mysql> SELECT REGEXP_LIKE('Bn', '^Ba?n');                      -> 1
    mysql> SELECT REGEXP_LIKE('Ban', '^Ba?n');                     -> 1
    mysql> SELECT REGEXP_LIKE('Baan', '^Ba?n');                    -> 0
  • de|abc

    选择;匹配 deabc 序列中的任何一个。

    mysql> SELECT REGEXP_LIKE('pi', 'pi|apa');                     -> 1
    mysql> SELECT REGEXP_LIKE('axe', 'pi|apa');                    -> 0
    mysql> SELECT REGEXP_LIKE('apa', 'pi|apa');                    -> 1
    mysql> SELECT REGEXP_LIKE('apa', '^(pi|apa)$');                -> 1
    mysql> SELECT REGEXP_LIKE('pi', '^(pi|apa)$');                 -> 1
    mysql> SELECT REGEXP_LIKE('pix', '^(pi|apa)$');                -> 0
  • (abc)*

    匹配零个或多个 abc 序列。

    mysql> SELECT REGEXP_LIKE('pi', '^(pi)*$');                    -> 1
    mysql> SELECT REGEXP_LIKE('pip', '^(pi)*$');                   -> 0
    mysql> SELECT REGEXP_LIKE('pipi', '^(pi)*$');                  -> 1
  • {1}, {2,3}

    重复;{n}{m,n} 表示法提供了一种更通用的方式来编写正则表达式,以匹配前一个原子(或“piece”)的多个实例。mn 是整数。

    • a*

      可以写作 a{0,}

    • a+

      可以写作 a{1,}

    • a?

      可以写作 a{0,1}

    更准确地说,a{n} 精确匹配 na 实例。a{n,} 匹配 n 或更多个 a 实例。a{m,n} 匹配 mna 实例,包括这两个数字。如果同时给出了 mn,则 m 必须小于或等于 n

    mysql> SELECT REGEXP_LIKE('abcde', 'a[bcd]{2}e');              -> 0
    mysql> SELECT REGEXP_LIKE('abcde', 'a[bcd]{3}e');              -> 1
    mysql> SELECT REGEXP_LIKE('abcde', 'a[bcd]{1,10}e');           -> 1
  • [a-dX], [^a-dX]

    匹配任何字符,该字符是(或不是,如果使用 ^a, b, c, dX 之一。一个 - 字符在两个其他字符之间形成一个范围,该范围匹配从第一个字符到第二个字符的所有字符。例如,[0-9] 匹配任何十进制数字。要包含一个文字 ] 字符,它必须紧跟在开括号 [ 之后。要包含一个文字 - 字符,它必须写在第一或最后。任何没有定义特殊含义的字符在 [] 对中只匹配自己。

    mysql> SELECT REGEXP_LIKE('aXbc', '[a-dXYZ]');                 -> 1
    mysql> SELECT REGEXP_LIKE('aXbc', '^[a-dXYZ]$');               -> 0
    mysql> SELECT REGEXP_LIKE('aXbc', '^[a-dXYZ]+$');              -> 1
    mysql> SELECT REGEXP_LIKE('aXbc', '^[^a-dXYZ]+$');             -> 0
    mysql> SELECT REGEXP_LIKE('gheis', '^[^a-dXYZ]+$');            -> 1
    mysql> SELECT REGEXP_LIKE('gheisa', '^[^a-dXYZ]+$');           -> 0
  • [=character_class=]

    在括号表达式中(使用 [] 编写),[=character_class=] 代表一个等价类。它匹配所有具有相同排序值的字符,包括自己。例如,如果 o(+) 是一个等价类的成员,那么 [[=o=]], [[=(+)=]][o(+)] 都是同义的。一个等价类不能用作范围的端点。

  • [:character_class:]

    在括号表达式中(使用 [] 编写),[:character_class:] 代表一个字符类,该类匹配所有属于该类的字符。下表列出了标准类名。这些名称来自 ctype(3) 手册页中的字符类定义。一个特定的locale可能提供其他类名。一个字符类不能用作范围的端点。

    Character Class Name Meaning
    alnum 字母数字字符
    alpha 字母字符
    blank 空白字符
    cntrl 控制字符
    digit 数字字符
    graph 图形字符
    lower 小写字母字符
    print 图形或空格字符
    punct 标点符号字符
    space 空格、制表符、新行和回车符
    upper 大写字母字符
    xdigit 十六进制数字字符
    mysql> SELECT REGEXP_LIKE('justalnums', '[[:alnum:]]+');       -> 1
    mysql> SELECT REGEXP_LIKE('!!', '[[:alnum:]]+');               -> 0

    因为 ICU 知道所有字母字符在 utf16_general_ci 中,一些字符类可能不如字符范围快。例如, [a-zA-Z] 已知比 [[:alpha:]] 快得多,而 [0-9] 通常比 [[:digit:]] 快得多。

要在正则表达式中使用特殊字符的文字实例,请在前面加上两个反斜杠(\)字符。MySQL 解析器解释其中一个反斜杠,而正则表达式库解释另一个反斜杠。例如,要匹配包含特殊 + 字符的字符串 1+2,只有以下正则表达式是正确的:

mysql> SELECT REGEXP_LIKE('1+2', '1+2');                       -> 0
mysql> SELECT REGEXP_LIKE('1+2', '1\+2');                      -> 0
mysql> SELECT REGEXP_LIKE('1+2', '1\\+2');                     -> 1

正则表达式资源控制

REGEXP_LIKE() 和类似函数使用资源,可以通过设置系统变量来控制:

  • 匹配引擎使用内存来存储其内部堆栈。要控制堆栈的最大可用内存(以字节为单位),请设置 regexp_stack_limit 系统变量。

  • 匹配引擎以步骤操作。要控制引擎执行的最大步骤数(从而间接控制执行时间),请设置 regexp_time_limit 系统变量。因为这个限制是以步骤数表示的,因此它只间接影响执行时间。通常,它是毫秒级别的。