mysql字符串正则表达式及说明

2022-11-13 15:11:37 mysql 字符串 正则表达式

概述

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

正则表达式是指定复杂搜索的模式的有力方式。本文讨论可用于正则表达式匹配的操作符,并举例说明可以用于正则表达式操作的一些特殊字符和构造。

Mysql使用了Henry Spencer的正则表达式实现,这是为了符合POSIX 1003.2。mysql使用扩展版本支持sql语句中的正则表达式模式匹配操作。

本文不包含 Henry Spencer’s regex(7)手册页中可以找到的所有细节。该手册页包含在MySQL源代码发行版中,在regex中,在regex目录下的文件。

正则表达式运算符

expr NOT REGEXP pat, expr NOT RLIKE pat

这与NOT(expr REGEXP pat)相同。

expr REGEXP pat, expr RLIKE pat

如果字符串expr与模式pat指定的正则表达式匹配,则返回1。如果expr或pat为空,返回值为空。

RLIKE是REGEXP的同义词。

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

Note

因为MySQL使用字符串中的C转义语法(例如,\n代表换行符),所以您必须将您在REGEXP参数中使用的任何\都增加一倍。

正则表达式操作在决定字符类型和执行比较时使用字符串表达式和模式参数的字符集和排序。如果参数具有不同的字符集或排序规则,则强制规则适用于第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 |
+---------------------+
mysql> SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
+----------------+-----------------------+
| 'a' REGEXP 'A' | 'a' REGEXP BINARY 'A' |
+----------------+-----------------------+
|              1 |                     0 |
+----------------+-----------------------+

警告

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

正则表达式语法

正则表达式描述一组字符串。最简单的正则表达式是没有特殊字符的表达式。例如,正则表达式hello匹配hello和其他内容。

另一类正则表达式使用某些特殊结构,以便它们能够匹配多个字符串。例如,正则表达式“hello|world“包含 |,匹配hello或world。

作为一个更复杂的例子,正则表达式B[an]*s匹配任何字符串Bananas、Baaaaas、Bs和任何以B开头的字符串,以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*

匹配任意一个或者多个字符

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

匹配任意一个或者多个字符

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

匹配0或1个字符。

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)*

匹配0或多个序列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* 
可以写成{0}。

* a+ 
可以写成{1}。

* a? 
可以写成{0,1}。

更确切地说,一个{n}恰好与n个实例匹配,一个{n,}匹配n个或多个实例,一个{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]匹配任何十进制数字。要包含一个文字字符,它必须立即跟随开头的括号[。要包含一个文字字符,必须先写或最后写。任何没有在[]对中定义特殊含义的字符只匹配它自己。

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.]

在一个括号表达式中(使用[和]),匹配该排序元素的字符序列。字符要么是单个字符,要么是像newline这样的字符名称。

下表列出了允许的字符名称。

下表显示了允许的字符名称和它们匹配的字符。对于以数字值表示的字符,值在八进制中表示。

NameCharacterNameCharacter
NUL0SOH001
STX002ETX003
EOT004ENQ005
ACK006BEL007
alert007BS010
backspace‘\b’HT011
tab‘\t’LF012
newline‘\n’VT013
vertical-tab‘\v’FF014
fORM-feed‘\f’CR015
carriage-return‘\r’SO016
SI017DLE020
DC1021DC2022
DC3023DC4024
NAK025SYN026
ETB027CAN030
EM031SUB032
ESC033IS4034
FS034IS3035
GS035IS2036
RS036IS1037
US037space’ ‘
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‘~’
DEL177  
mysql> SELECT '~' REGEXP '[[.~.]]';                     -> 1
mysql> SELECT '~' REGEXP '[[.tilde.]]';                 -> 1
  • [=character_class=]

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

  • [:character_class:]

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

Character Class NameMeaning
alnumAlphanumeric characters
alphaAlphabetic characters
blankWhitespace characters
cntrlControl characters
digitDigit characters
graphGraphic characters
lowerLowercase alphabetic characters
printGraphic or space characters
punctPunctuation characters
spaceSpace, tab, newline, and carriage return
upperUppercase alphabetic characters
xdigitHexadecimal digit characters
Character Class NameMeaning
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

参考文档:https://dev.mysql.com/doc/refman/5.7/en/regexp.html

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

相关文章