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 REGEXPpat
expr
NOT RLIKEpat
这等同于
NOT (
。expr
REGEXPpat
) -
,expr
REGEXPpat
expr
RLIKEpat
如果字符串
expr
匹配指定的正则表达式模式pat
,则返回 1,否则返回 0。如果expr
或pat
是NULL
,则返回NULL
。REGEXP
和RLIKE
是REGEXP_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。如果expr
或pat
是NULL
,则返回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。如果expr
或pat
是NULL
,则返回NULL
。模式可以是一个扩展的正则表达式,语法在正则表达式语法中讨论。模式不需要是字面字符串。例如,它可以指定为字符串表达式或表格列。
可选的
match_type
参数是一个字符串,可以包含以下字符之一或多个,指定如何进行匹配:-
c
:区分大小写的匹配。 -
i
:不区分大小写的匹配。 -
m
:多行模式。识别字符串中的行结束符。默认情况下,匹配行结束符只能在字符串的开始和结束。 -
n
:字符.
匹配行结束符。默认情况下,.
匹配停止在行结束符处。 -
u
:Unix-only行结束符。只有换行符被.
、^
和$
匹配操作符识别为行结束符。
如果在
match_type
中指定了矛盾的选项,最后一个选项将优先。默认情况下,正则表达式操作使用
expr
和pat
参数的字符集和排序规则来确定字符类型和进行比较。如果参数具有不同的字符集或排序规则,遵循 coerceibility 规则,如Section 12.8.4, “Collation Coercibility in Expressions”中描述的那样。参数可以指定明确的排序指示符来更改比较行为。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
可以指定c
或i
字符来覆盖默认的大小写敏感性。异常:如果任何一个参数是一个二进制字符串,参数将被处理为大小写敏感的二进制字符串,即使match_type
包含i
字符。NoteMySQL 使用 C 逃逸语法在字符串中(例如,
\n
来表示换行符)。如果您想让expr
或pat
参数包含一个字面上的\
,您必须将其双倍化。 (除非启用了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
,并返回结果字符串。如果expr
,pat
或repl
为NULL
,则返回值为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
。如果expr
或pat
为NULL
,则返回值为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
包含|
Alternation 操作符,并且匹配hello
或world
。
作为一个更复杂的示例,正则表达式B[an]*s
匹配任何以B
开头,结尾为s
,中间包含任意数量的a
或n
字符的字符串。
以下是正则表达式的一些基本特殊字符和构造。关于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)
within-pattern 修饰符)。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
Alternation;匹配
de
或abc
的序列。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
}{
表示法提供了一种更通用的方式来编写正则表达式,以匹配多个前一个原子(或“piece”)的模式。m
,n
}m
和n
是整数。-
a*
可以写作
a{0,}
。 -
a+
可以写作
a{1,}
。 -
a?
可以写作
a{0,1}
。
为了更精确地描述,
a{
匹配恰好n
}n
个a
。a{
匹配n
,}n
或更多的a
。a{
匹配m
,n
}m
到n
个a
,包括。 如果都给出了m
和n
,那么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
、d
或X
。一个-
字符在两个其他字符之间形成一个范围,匹配所有从第一个字符到第二个字符的字符。例如,[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
要在正则表达式中使用特殊字符的字面值实例,需要在其前面添加两个反斜杠(\)字符。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
系统变量。由于该限制是以步骤为单位表示,因此它间接地影响执行时间。通常,它在毫秒级别上。