表 12.14 正则表达式函数和运算符
姓名 | 描述 |
---|---|
NOT REGEXP |
REGEXP 的否定 |
REGEXP |
字符串是否匹配正则表达式 |
REGEXP_INSTR() |
子串匹配正则表达式的起始索引 |
REGEXP_LIKE() |
字符串是否匹配正则表达式 |
REGEXP_REPLACE() |
替换匹配正则表达式的子字符串 |
REGEXP_SUBSTR() |
返回匹配正则表达式的子串 |
RLIKE |
字符串是否匹配正则表达式 |
正则表达式是一种为复杂搜索指定模式的强大方法。本节讨论可用于正则表达式匹配的函数和运算符,并通过示例说明一些可用于正则表达式运算的特殊字符和结构。另见第 3.3.4.7 节,“模式匹配”。
MySQL 使用 Unicode 国际组件 (ICU) 实现正则表达式支持,它提供完整的 Unicode 支持并且是多字节安全的。(在 MySQL 8.0.4 之前,MySQL 使用 Henry Spencer 的正则表达式实现,它以字节方式运行并且不是多字节安全的。有关使用正则表达式的应用程序可能受实现更改影响的方式的信息,请参阅正则表达式兼容性注意事项。)
在 MySQL 8.0.22 之前,可以对这些函数使用二进制字符串参数,但它们会产生不一致的结果。在 MySQL 8.0.22 及更高版本中,拒绝将二进制字符串与任何 MySQL 正则表达式函数一起使用
ER_CHARACTER_SET_MISMATCH
。
,expr
NOT REGEXPpat
expr
NOT RLIKEpat
这与.
NOT (
expr
REGEXPpat
)
,expr
REGEXPpat
expr
RLIKEpat
expr
如果字符串与 pattern 指定的正则表达式匹配,则 返回 1pat
,否则返回 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
返回与 pattern 指定的正则表达式匹配的 字符串的子字符串的起始索引,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
如果字符串与 pattern 指定的正则表达式匹配,则 返回 1pat
,否则返回 0。如果expr
或pat
是NULL
,则返回值为NULL
。该模式可以是一个扩展的正则表达式,其语法在 正则表达式语法中讨论。模式不必是文字字符串。例如,它可以指定为字符串表达式或表列。
可选
match_type
参数是一个字符串,可以包含以下任何或所有指定如何执行匹配的字符:c
: 区分大小写匹配。i
: 不区分大小写的匹配。m
: 多行模式。识别字符串中的行终止符。默认行为是仅在字符串表达式的开头和结尾匹配行终止符。n
:.
字符匹配行终止符。默认是.
匹配停止在一行的末尾。u
: Unix-only 行结尾。只有换行符被识别为以 、 和匹配运算符结尾.
的^
行$
。
如果在 中指定了指定相互矛盾的选项的字符
match_type
,则最右边的优先。默认情况下,正则表达式操作 在确定字符类型和执行比较时使用
expr
和 参数的字符集和排序规则。pat
如果参数具有不同的字符集或排序规则,则适用强制性规则,如 第 10.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
可以用c
或i
字符指定以覆盖默认的区分大小写。例外:如果任一参数是二进制字符串,则参数将以区分大小写的方式作为二进制字符串处理,即使match_type
包含该i
字符也是如此。笔记MySQL 在字符串中使用 C 转义语法(例如,
\n
表示换行符)。如果您希望您的expr
orpat
参数包含 literal\
,则必须将其加倍。(除非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()
。
MySQL 8.0.17之前,该函数返回的结果使用
UTF-16
字符集;MySQL 8.0.17及以后版本,使用匹配搜索表达式的字符集和排序规则。(缺陷 #94203,缺陷 #29308212)有关匹配如何发生的其他信息,请参阅 的说明
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
与 pattern 指定的正则表达式匹配的 字符串的子字符串 。如果或 是,则返回值为。pat
NULL
expr
pat
NULL
NULL
REGEXP_SUBSTR()
采用这些可选参数:pos
:expr
开始搜索的位置。如果省略,默认值为 1。occurrence
:要搜索的匹配项。如果省略,默认值为 1。match_type
:指定如何执行匹配的字符串。含义如对 所述REGEXP_LIKE()
。
MySQL 8.0.17之前,该函数返回的结果使用
UTF-16
字符集;MySQL 8.0.17及以后版本,使用匹配搜索表达式的字符集和排序规则。(缺陷 #94203,缺陷 #29308212)有关匹配如何发生的其他信息,请参阅 的说明
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
包含
|
交替运算符并匹配hello
or world
。
作为一个更复杂的示例,正则表达式
B[an]*s
匹配任何字符串
Bananas
、Baaaaas
、
Bs
,以及任何其他以 a 开头
B
、以 an 结尾并且中间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)
模式内修饰符)。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
交替; 匹配任一序列
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
}{
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]
匹配任何十进制数字。要包含文字]
字符,它必须紧跟在左括号之后[
。要包含文字-
字符,它必须写在最前面或最后。任何在字符中没有定义的特殊含义的字符[]
pair 只匹配它自己。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=]
在括号表达式(使用
[
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 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
系统变量。因为此限制表示为步骤数,所以它只会间接影响执行时间。通常,它是毫秒级的。
在 MySQL 8.0.4 之前,MySQL 使用 Henry Spencer 正则表达式库来支持正则表达式操作,而不是 International Components for Unicode (ICU)。以下讨论描述了 Spencer 和 ICU 库之间可能影响应用程序的差异: