MySQL数据库的REGEXP函数是一种正则表达式函数,用于在文本中匹配正则表达式。它可以在查询语句中使用,以便根据特定的模式搜索和筛选数据。本文将介绍REGEXP函数的语法、案例以及注意事项。RLIKE 是REGEXP的一个同义词。REGEXP函数不区分大小写。
expr REGEXP pat
或
expr RLIKE pat
expr(字符串)匹配指定的 pat(正则表达式)字符串就返回1 ,否则0。
如果 expr 或 pat 是NULL ,返回值是NULL。
mysql> SELECT 'Michael!' REGEXP '.*'; +------------------------+ | 'Michael!' REGEXP '.*' | +------------------------+ | 1 | +------------------------+ mysql> SELECT 'new*\n*line' REGEXP 'new\\*.\\*line'; +---------------------------------------+ | 'new*\n*line' REGEXP 'new\\*.\\*line' | +---------------------------------------+ | 1 | +---------------------------------------+ mysql> SELECT 'a' REGEXP '^[a-d]'; +---------------------+ | 'a' REGEXP '^[a-d]' | +---------------------+ | 1 | +---------------------+
MySQL regexp匹配所使用的字符,与常规正则表达式相同:
模式 | 模式匹配什么 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
. | 匹配任意单个字符 |
[...] | 匹配方括号间列出的任意字符 |
[^...] | 匹配方括号间未列出的任意字符 |
p1|p2|p3 | 交替匹配任意 p1 或 p2 或 p3 |
* | 匹配前面的元素的零次或多次 |
+ | 匹配前面的元素的一次或多次 |
? | 匹配前面的元素的零次或一次 |
{n} | 匹配前面的元素 n 次 |
{m,n} | 匹配前面的元素 m 至 n 次 |
正则表达式描述一组字符串。最简单的正则表达式是其中没有特殊字符的表达式。例如正则表达式 hello 匹配hello 什么都没有。
非平凡的正则表达式使用某些特殊的构造,这样它们可以匹配多个字符串。例如正则表达式hello|world 包含 | 替换操作符和匹配者hello 或world .
更复杂的例子,正则表达式 B[an]*s 匹配任何一个 Bananas ,Baaaaas , Bs ,以及任何以 B开头结尾是s ,并载有任何数目的a 或 n 中间的角色。
^
匹配一个字符串的开头.
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?
匹配0或1a 序列。
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是整数。
1、a*
可写为a{0,} .
2、a+
可写为a{1,} .
3、a?
可写为a{0,1} .
更准确地说,a{n}恰好匹配的n个实例a。匹配n或多个实例 a。 a{m,n}匹配m到n个实例。如果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的任何字符。另外两个字符之间的a字符形成一个匹配从第一个字符到第二个字符的所有字符的范围。
例如,[0-9]匹配任何十进制数字。
要包含一个文字]字符,它必须立即跟随开括号[。要包含字符,必须先写或最后写。任何在[]对中没有定义的特殊含义的字符都只匹配其本身。
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.]
在括号表达式中(使用[和]编写)中,匹配该排序元素的字符序列。字符可以是单个字符,也可以是像换行符这样的字符名称。
下表列出了允许的字符名称。下表显示了允许的字符名称及其匹配的字符。对于以数值表示的字符,这些值用八进制表示。
名称 | 字符 | 名称 | 字符 |
---|---|---|---|
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=]
在括号表达式(使用[和]编写)中,[=pirte_class=]表示一个等价类。它匹配具有相同排序规则值的所有字符,包括它本身。
例如,如果o和(+)是等价类的成员,那么[[=o=]]、[[=(+)=]]和[o(+)]都是同义的。
一个等价类不能被用作一个范围的端点。
[:character_class:]
在括号表达式(使用[和]编写)中,[:character_class:]表示与属于该类的所有字符的字符类匹配。
下表列出了标准的类名。
一个特定的区域设置可以提供其他的类名。一个字符类不能被用作一个范围的端点。
字符类名称 | 意义 |
---|---|
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
下面是一些使用REGEXP函数的案例,以帮助您更好地理解其用法:
假设我们有一个名为users的表,其中包含一个名为email的列,我们想要查找包含字符串example.com的所有行。我们可以使用以下查询:
SELECT * FROM users WHERE email REGEXP 'example.com';
如果我们想要查找以字符串john开头的所有email行,可以使用以下查询:
SELECT * FROM users WHERE email REGEXP '^john';
假设我们想要查找所有包含数字的phone_number列,我们可以使用以下查询:
SELECT * FROM users WHERE phone_number REGEXP '[0-9]';
在使用REGEXP函数时,需要注意以下几点:
在正则表达式模式中,可以使用不同的特殊字符来表示不同的模式匹配。例如,.表示匹配任意字符,*表示匹配前一个字符的零个或多个实例。如果您需要更深入了解正则表达式模式,请查阅MySQL官方文档或其他相关资料。
在某些情况下,使用REGEXP函数可能会导致性能问题。如果需要搜索的列包含大量数据,或者正则表达式模式非常复杂,查询可能会变得很慢。在这种情况下,可以考虑使用其他搜索方法或优化数据库结构。
注意在查询语句中使用REGEXP函数可能会使查询变得复杂且难以维护。如果可能的话,尽量使用简单的查询语句或使用其他更适合的函数来达到相同的目的。
在使用REGEXP函数时,确保正则表达式模式是正确的。错误的模式可能会导致查询返回不正确的结果或者出现错误。