正则表达式是一种为复杂搜索指定模式的强大方法。本节讨论可用于正则表达式匹配的运算符,并通过示例说明一些可用于正则表达式运算的特殊字符和结构。另见 第 3.3.4.7 节,“模式匹配”。
MySQL 使用 Henry Spencer 的正则表达式实现,旨在与 POSIX 1003.2 保持一致。MySQL 使用扩展版本支持 SQL 语句中的正则表达式模式匹配操作。本节不包含可以在 Henry Spencer 的
regex(7)
手册页中找到的所有详细信息。该手册页包含在 MySQL 源代码分发中,在
目录regex.7
下的
文件中regex
。
,expr
NOT REGEXPpat
expr
NOT RLIKEpat
这与.
NOT (
expr
REGEXPpat
)
,expr
REGEXPpat
expr
RLIKEpat
expr
如果字符串与 pattern 指定的正则表达式匹配,则 返回 1pat
,否则返回 0。如果expr
或pat
是NULL
,则返回值为NULL
。该模式可以是一个扩展的正则表达式,其语法在 正则表达式语法中讨论。模式不必是文字字符串。例如,它可以指定为字符串表达式或表列。
笔记MySQL 在字符串中使用 C 转义语法(例如,
\n
表示换行符)。如果您希望您的expr
orpat
参数包含 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 | +---------------------+
正则表达式描述一组字符串。最简单的正则表达式是其中没有特殊字符的正则表达式。例如,正则表达式
hello
匹配hello
,仅此而已。
非平凡的正则表达式使用某些特殊的结构,以便它们可以匹配多个字符串。例如,正则表达式hello|world
包含
|
交替运算符并匹配hello
or world
。
作为一个更复杂的示例,正则表达式
B[an]*s
匹配任何字符串
Bananas
、Baaaaas
、
Bs
,以及任何其他以 a 开头
B
、以 an 结尾并且中间s
包含任意数量的a
或
n
字符的字符串。
运算符的正则表达式
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
交替; 匹配任一序列
de
或abc
.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
}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
m
并且n
必须在从0
到RE_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
,d
或X
.-
两个其他字符之间的字符形成一个范围,该范围匹配从第一个字符到第二个字符的所有字符。 例如,[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