Documentation Home

12.8.2 正则表达式

表 12.14 正则表达式函数和运算符

姓名 描述
NOT REGEXP REGEXP 的否定
REGEXP 字符串是否匹配正则表达式
RLIKE 字符串是否匹配正则表达式

正则表达式是一种为复杂搜索指定模式的强大方法。本节讨论可用于正则表达式匹配的运算符,并通过示例说明一些可用于正则表达式运算的特殊字符和结构。另见 第 3.3.4.7 节,“模式匹配”

MySQL 使用 Henry Spencer 的正则表达式实现,旨在与 POSIX 1003.2 保持一致。MySQL 使用扩展版本支持 SQL 语句中的正则表达式模式匹配操作。本节不包含可以在 Henry Spencer 的 regex(7)手册页中找到的所有详细信息。该手册页包含在 MySQL 源代码分发中,在 目录regex.7下的 文件中regex

正则表达式函数和运算符说明

  • expr NOT REGEXP pat, expr NOT RLIKE pat

    这与. NOT (expr REGEXP pat)

  • expr REGEXP pat, expr RLIKE pat

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

    RLIKE是的同义词REGEXP

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

    笔记

    MySQL 在字符串中使用 C 转义语法(例如, \n表示换行符)。如果您希望您的 expror pat参数包含 literal \,则必须将其加倍。(除非 NO_BACKSLASH_ESCAPES 启用了 SQL 模式,在这种情况下不使用转义字符。)

    在确定字符类型和执行比较时,正则表达式操作使用字符串表达式和模式参数的字符集和排序规则。如果参数具有不同的字符集或排序规则,则适用强制性规则,如 第 10.8.4 节,“表达式中的排序规则强制性”中所述。如果任一参数是二进制字符串,则这些参数将以区分大小写的方式作为二进制字符串进行处理。

    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 |
    +---------------------+
    警告

    REGEXPand 运算符 以RLIKE 字节方式工作,因此它们不是多字节安全的,并且可能会在多字节字符集上产生意外结果。此外,这些运算符通过字符的字节值和重音字符比较字符可能不相等,即使给定的排序规则将它们视为相等。

正则表达式语法

正则表达式描述一组字符串。最简单的正则表达式是其中没有特殊字符的正则表达式。例如,正则表达式 hello匹配hello,仅此而已。

非平凡的正则表达式使用某些特殊的结构,以便它们可以匹配多个字符串。例如,正则表达式hello|world包含 |交替运算符并匹配helloor world

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

运算符的正则表达式 REGEXP可以使用以下任何特殊字符和结构:

  • ^

    匹配字符串的开头。

    mysql> SELECT 'fo\nfo' REGEXP '^fo$';                   -> 0
    mysql> SELECT 'fofo' REGEXP '^fo';                      -> 1
  • $

    匹配字符串的结尾。

    mysql> SELECT 'fo\no' REGEXP '^fo\no$';                 -> 1
    mysql> SELECT 'fo\no' REGEXP '^fo$';                    -> 0
  • .

    匹配任何字符(包括回车和换行)。

    mysql> SELECT 'fofo' REGEXP '^f.*$';                    -> 1
    mysql> SELECT 'fo\r\nfo' REGEXP '^f.*$';                -> 1
  • a*

    匹配零个或多个a 字符的任意序列。

    mysql> SELECT 'Ban' REGEXP '^Ba*n';                     -> 1
    mysql> SELECT 'Baaan' REGEXP '^Ba*n';                   -> 1
    mysql> SELECT 'Bn' REGEXP '^Ba*n';                      -> 1
  • a+

    匹配一个或多个a 字符的任意序列。

    mysql> SELECT 'Ban' REGEXP '^Ba+n';                     -> 1
    mysql> SELECT 'Bn' REGEXP '^Ba+n';                      -> 0
  • a?

    匹配零个或一个a字符。

    mysql> SELECT 'Bn' REGEXP '^Ba?n';                      -> 1
    mysql> SELECT 'Ban' REGEXP '^Ba?n';                     -> 1
    mysql> SELECT 'Baan' REGEXP '^Ba?n';                    -> 0
  • de|abc

    交替; 匹配任一序列 deabc.

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

    匹配序列的零个或多个实例 abc

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

    重复; 和 符号提供了一种更通用的编写正则表达式的方法,这些正则表达式与模式的前一个原子(或片段)的 多次出现相匹配。并且 是整数。 {n}{m,n}mn

    • a*

      可以写成a{0,}.

    • a+

      可以写成a{1,}.

    • a?

      可以写成a{0,1}.

    更准确地说, 完全 匹配. 的匹配项或多个实例 。 通过 , 包含的实例进行 匹配。如果同时 给出 和 ,则必须小于或等于 。 a{n}naa{n,}naa{m,n}mnamnmn

    m并且 n必须在从 0RE_DUP_MAX (默认 255)的范围内,包括在内。

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

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

    mysql> SELECT 'aXbc' REGEXP '[a-dXYZ]';                 -> 1
    mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]$';               -> 0
    mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]+$';              -> 1
    mysql> SELECT 'aXbc' REGEXP '^[^a-dXYZ]+$';             -> 0
    mysql> SELECT 'gheis' REGEXP '^[^a-dXYZ]+$';            -> 1
    mysql> SELECT 'gheisa' REGEXP '^[^a-dXYZ]+$';           -> 0
  • [.characters.]

    在括号表达式(使用 [and编写])中,匹配该整理元素的字符序列。 characters是单个字符或字符名称,如newline. 下表列出了允许的字符名称。

    下表显示了允许的字符名称及其匹配的字符。对于以数值形式给出的字符,这些值以八进制表示。

    姓名 特点 姓名 特点
    NUL 0 SOH 001
    STX 002 ETX 003
    EOT 004 ENQ 005
    ACK 006 BEL 007
    alert 007 BS 010
    backspace '\b' HT 011
    tab '\t' LF 012
    newline '\n' VT 013
    vertical-tab '\v' FF 014
    form-feed '\f' CR 015
    carriage-return '\r' SO 016
    SI 017 DLE 020
    DC1 021 DC2 022
    DC3 023 DC4 024
    NAK 025 SYN 026
    ETB 027 CAN 030
    EM 031 SUB 032
    ESC 033 IS4 034
    FS 034 IS3 035
    GS 035 IS2 036
    RS 036 IS1 037
    US 037 space ' '
    exclamation-mark '!' quotation-mark '"'
    number-sign '#' dollar-sign '$'
    percent-sign '%' ampersand '&'
    apostrophe '\'' left-parenthesis '('
    right-parenthesis ')' asterisk '*'
    plus-sign '+' comma ','
    hyphen '-' hyphen-minus '-'
    period '.' full-stop '.'
    slash '/' solidus '/'
    zero '0' one '1'
    two '2' three '3'
    four '4' five '5'
    six '6' seven '7'
    eight '8' nine '9'
    colon ':' semicolon ';'
    less-than-sign '<' equals-sign '='
    greater-than-sign '>' question-mark '?'
    commercial-at '@' left-square-bracket '['
    backslash '\\' reverse-solidus '\\'
    right-square-bracket ']' circumflex '^'
    circumflex-accent '^' underscore '_'
    low-line '_' grave-accent '`'
    left-brace '{' left-curly-bracket '{'
    vertical-line '|' right-brace '}'
    right-curly-bracket '}' tilde '~'
    DEL 177
    mysql> SELECT '~' REGEXP '[[.~.]]';                     -> 1
    mysql> SELECT '~' REGEXP '[[.tilde.]]';                 -> 1
  • [=character_class=]

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

  • [:character_class:]

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

    字符类名称 意义
    alnum 字母数字字符
    alpha 字母字符
    blank 空白字符
    cntrl 控制字符
    digit 数字字符
    graph 图形字符
    lower 小写字母字符
    print 图形或空格字符
    punct 标点符号
    space 空格、制表符、换行符和回车
    upper 大写字母字符
    xdigit 十六进制数字字符
    mysql> SELECT 'justalnums' REGEXP '[[:alnum:]]+';       -> 1
    mysql> SELECT '!!' REGEXP '[[:alnum:]]+';               -> 0
  • [[:<:]], [[:>:]]

    这些标记代表单词边界。它们分别匹配单词的开头和结尾。单词是单词字符的序列,其前面或后面都没有单词字符。单词字符是alnum 类中的字母数字字符或下划线 ( _)。

    mysql> SELECT 'a word a' REGEXP '[[:<:]]word[[:>:]]';   -> 1
    mysql> SELECT 'a xword a' REGEXP '[[:<:]]word[[:>:]]';  -> 0

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

mysql> SELECT '1+2' REGEXP '1+2';                       -> 0
mysql> SELECT '1+2' REGEXP '1\+2';                      -> 0
mysql> SELECT '1+2' REGEXP '1\\+2';                     -> 1