MySQL正则表达式(REGEXP)
正则表达式⽤来匹配⽂本的特殊的串(字符集合)(匹配⽂本,将⼀个模式(正则表达式)与⼀个⽂本串进⾏⽐较)。
LIKE 和 REGEXP之间的重要差别
LIKE 匹配整个列,如果被匹配的⽂本在列值中出现,LIKE 将不会到它,相应的⾏也不会被返回(除⾮使⽤通配符)。⽽ REGEXP 在列值内进⾏匹配,如果被匹配的⽂本在列值中出现,REGEXP 将会到它,相应的⾏将被返回,并且 REGEXP 能匹配整个列值(与 LIKE 相同的作⽤)。
正则表达式匹配不区分⼤⼩写
MySQL  的正则表达式匹配(⾃3.23.4版本后)不区分⼤⼩写(即⼤写和⼩写都匹配)。为区分⼤⼩写,可以使⽤ BINARY 关键字,例如:WHHERE name REGEXP BINARY 'Hern .000'。
简单的正则表达式测试
可以在不使⽤数据库表的情况下⽤ SELECT 语句来测试正则表达式,REGEXP 检查总是返回0(没有匹配)或1(匹配)。可以⽤带⽂字串的 REGEXP 来测试表达式,并试验它们。
例如:检测 'Hern' 中是否含有数字
SELECT 'Hern' REGEXP '[0-9]';
结果将返回0(因为 ‘Hern’ 中没有数字)
空⽩元字符(特殊含义的字符)
⽤双反斜杠(\\)来引⽤元字符(具有特殊含义的字符)。常⽤引⽤元字符:
注意:
1、多数正则表达式实现使⽤单个反斜杠转义特殊字符,⼀遍能使⽤这些字符本⾝,但是MySQL要求两个反斜杠(MySQL⾃⼰解释⼀个,正则表达式库解释另⼀个)。
2、^ 符号的双重⽤途: ^在集合中(⽤ [ ] 定义)时⽤它来否定该集合,否则⽤来指定串的开始处。
匹配字符类
⼦字符类其它信息
[:alpha:]匹配当前归类中的⼤写和⼩写字母字符。例如,'[0-9]{3}[[:alpha:]]{2}' 匹配三个数字,后跟两个字母。
[:alnum:]匹配当前归类中的数字、⼤写和⼩写字母字符。例如,'[[:alnum:]]+' 匹配含有⼀个或多个字母和数字的字符串。
[:digit:]匹配当前归类中的数字。例如,'[[:digit:]-]+' 匹配含有⼀个或多个数字或横线的字符串。同样,'[^[:digit:]-]+' 匹配含有⼀个或多个不是数字或横线的字符的字符串。
[:lower:]匹配当前归类中的⼩写字母字符。例如,'[[:lower:]]' 不匹配 A,因为 A 为⼤写。
[:space:]匹配单个空格 (' ')。例如,搜索 Contacts.City 以查任何名称为两个词的城市:SELECT City FROM Contacts WHERE City REGEXP '.*[[:space:]].*';
[:upper:]匹配当前归类中的⼤写字母字符。例如,'[[:upper:]ab]' 与以下其中⼀项匹配:任何⼤写字母、a 或 b。[:whitespace:]匹配⼀个空⽩字符,例如,空格、制表符、换页符和回车符。
[:ascii:]匹配任何七位的 ASCII 字符(0 到 127 之间的顺序值)。
[:blank:]匹配⼀个空⽩区或⽔平制表符。[[:blank:]] 等效于 [ \t]。
[:cntrl:]匹配顺序值⼩于 32 或字符值为 127 的 ASCII 字符(控制字符)。控制字符包括换⾏符、换页符、退格符,等等。
[:graph:]匹配打印字符。
[[:graph:]] 等效于 [[:alnum:][:punct:]]。
[:print:]匹配打印字符和空格。
[[:print:]] 等效于 [[:graph:][:whitespace:]]。
[:punct:]匹配其中⼀个字符: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~.
[:punct:] ⼦字符类不能包括当前归类中可⽤的⾮ ASCII 标点字符。
[:word:]匹配当前归类中的字母、数字或下划线字符。[[:word:]] 等效于 [[:alnum:]_]。
[:xdigit:]匹配字符类 [0-9A-Fa-f] 中的字符。
正则表达式⽀持的其它语法约定
正则表达
式语法
名称和含义
\0xxx匹配值为 \0xxx 的字符,其中 xxx 是任何⼋进制数字序列,0 是零。例如,\0134 匹配反斜线。\a匹配报警字符。
\A ⽤在字符集外部以便匹配字符串的开头。等效于在字符集外部使⽤的 ^。
\b匹配退格字符。
\B匹配反斜线字符 (\)。
\c X匹配已命名的控制字符。例如,\cZ 代表 ctrl-Z。
\d 匹配当前归类中的⼀个数字。例如,以下语句搜索 Contacts.Phone 以查以 00 结尾的所有电话号码:SELECT Surname, Surname, City, Phone FROM Contacts WHERE Phone REGEXP '\\d{8}00';
\d 既可⽤在字符类的内部也可⽤在字符类的外部,等效于 [[:digit:]]。
\D 匹配数字以外的任何字符。它的作⽤与 \d 正好相反。
\D 既可⽤在字符类的内部也可⽤在字符类的外部,等效于 [^[:digit:]]。
在⽅括号内使⽤取⾮速记时请务必谨慎。[\D\S] 与 [^\d\s] 并不相同。后者匹配数字或空格以外的任何字符。所以它匹配 x,但不匹配 8。⽽前者匹配不是数字或不是空格(满⾜两个条件之⼀)的任何字符。因为数字不是空格,空格也不是数字,所
以 [\D\S] 可以匹配任何字符、数字、空格或其它字符。
\e匹配转义字符。
\E将由 \Q 启动的将元字符视为⾮元字符这⼀功能停⽌。
\f匹配换页符。
\n匹配换⾏符。
\Q将所有元字符视为⾮元字符,直到遇到 \E。例如,\Q[$\E 等效于 \[\$。\r匹配回车符。
\s 匹配⼀个被视为⽩空格的空格或字符。例如,从 Products.ProductName 中返回名称中⾄少有⼀个空格的所有产品名:SELECT Name FROM Products WHERE Name REGEXP '.*\\s.*';
\s 既可⽤在字符类的内部也可⽤在字符类的外部,等效于 [[:whitespace:]]。
\S 匹配⾮⽩空格字符。它的作⽤与 \d 正好相反,⽽等效于 [^[:whitespace:]]。
\S 既可⽤在字符类的内部也可⽤在字符类的外部。
在⽅括号内使⽤取⾮速记时请务必谨慎。[\D\S] 与 [^\d\s] 并不相同。后者匹配数字或空格以外的任何字符。所以它匹配 x,但不匹配 8。⽽前者匹配不是数字或不是空格(满⾜两个条件之⼀)的任何字符。因为数字不是空格,空格也不是数字,所
以 [\D\S] 可以匹配任何字符、数字、空格或其它字符。
\t匹配⽔平制表符。
\v匹配垂直制表符。
匹配当前归类中的字母字符、数字或下划线。例如,从 Contacts.Surname 返回长度正好为七个字母数字字符的所有姓:
\w 匹配当前归类中的字母字符、数字或下划线。例如,从 Contacts.Surname 返回长度正好为七个字母数字字符的所有姓:SELECT Surname FROM Contacts WHERE Surname REGEXP '\\w{7}';
\w 既可⽤在字符类的内部也可⽤在字符类的外部。等效于 [[:alnum:]_].。
\W 匹配当前归类中字母字符、数字或下划线以外的任何字符。它的作⽤与 \w 正好相反,⽽等效于 [^[:alnum:]_]。在字符类的内部和外部都可使⽤此正则表达式。
\x hh匹配值为 0x hh 的字符,其中 hh 最多为两个⼗六进制数字。例如,\x2D 等效于⼀个连字符。等效于 \x{hh}。
\x{hhh}匹配值为 0x hhh 的字符,其中 hhh 最多为三个⼗六进制数字。
\z 和 \Z匹配字符串结尾处的位置(⽽⾮字符)。等效于 $。
正则表达式断⾔
断⾔测试条件是否为真,并影响字符串中开始匹配的位置。断⾔不返回字符;最终匹配中不包括断⾔模式。REGEXP 搜索条件和REGEXP_SUBSTR 函数⽀持断⾔模式。
在尝试拆分字符串时,lookahead 和 lookbehind 断⾔对于 REGEXP_SUBSTR 将⾮常有⽤。例如,可以通过执⾏以下语句返回Customers 表的 Address 列中街道名称(不带街道编号)的列表:
SELECT REGEXP_SUBSTR( Street, '(?<=^\\S+\\s+).*$' )
FROM Customers;
另⼀个⽰例:假定您想要使⽤正则表达式来验证⼝令是否符合某些规则。可以使⽤类似于下⾯内容的零宽度断⾔:
IF password REGEXP '(?=.*[[:digit:]])(?=.*[[:alpha:]].*[[:alpha:]])[[:word:]]{4,12}'
MESSAGE 'Password conforms' TO CLIENT;
ELSE
MESSAGE 'Password does not conform' TO CLIENT;
END IF
password ⾄少有⼀位数(零宽度肯定断⾔ [[:digit:]])当满⾜以下条件时,⼝令有效:
password ⾄少有两个字母字符(零宽度肯定断⾔ [[:alpha:]].*[[:alpha:]])regexp like
password 只含有字母数字字符或下划线字符 ([[:word:]])
password 最少含有 4 个字符,最多含有 12 个字符 ({4,12})
下表包含 SQL Anywhere ⽀持的断⾔:
语法含义
(?=pattern)肯定的 lookahead 零宽度断⾔  查看字符串中的当前位置是否紧跟着出现了 pattern,⽽ pattern 不会成为匹配字符串的⼀部分。'A(?=B)' 匹配后⾯跟有 B 的 A,但不使 B 成为匹配的⼀部分。
例如,SELECT REGEXP_SUBSTR( 'in new york city', 'new(?=\\syork)'); 会返回⼦串 new,因为它后⾯紧跟着 '
york'(请注意 york 前⾯的空格)。
(?!pattern)否定的 lookahead 零宽度断⾔  查看字符串中的当前位置是否没有 紧跟着出现 pattern,⽽ pattern 不会成为匹配字符串的⼀部分。所以,'A(?!B)' 匹配后⾯未跟着 B 的 A。
例如,SELECT REGEXP_SUBSTR('new jersey', 'new(?!\\syork)'); 会返回⼦串 new。
(?<=pattern)肯定的 lookbehind 零宽度断⾔  查看字符串中的当前位置是否前⾯紧挨着出现了 pattern,⽽ pattern 不会成为匹配字符串的⼀部分。所以,'(?<=A)B' 匹配前⾯紧挨着 A 的 B,但不使 A 成为匹配的⼀部分。
例如,SELECT REGEXP_SUBSTR('new york', '(?<=new\\s)york'); 会返回⼦串 york。
(?<!pattern)否定的 lookbehind 零宽度断⾔  查看字符串中的当前位置的前⾯是否没有 紧挨着出现 pattern,⽽ pattern 不会成为匹配字符串的⼀部分。
例如,SELECT REGEXP_SUBSTR('about york', '(?<!new\\s)york'); 会返回⼦串 york。
(?>pattern)所属关系局部⼦表达式  仅匹配与 pattern 匹配的剩余字符串的最⼤前缀。
例如,在 'aa' REGEXP '(?>a*)a' 中,(?>a*) 匹配(并消耗)aa,⽽决不仅仅是前导 a。因此,'aa' REGEXP '(?>a*)a' 的计算结果为 false。
(?:pattern)⾮捕获块  该语法在功能上就等效于 pattern,是为实现兼容性⽽提供。
例如,在 'bb' REGEXP '(?:b*)b' 中,(?:b*) 匹配(并消耗)bb。但是,与所属关系局部⼦表达式不同,bb 中的最后⼀个b 会被放弃,以允许整个匹配成功(即,允许与在⾮捕获块的外部到的 b 匹配)。
同样,'a(?:bc|b)c' 匹配 abcc 和 abc。在匹配 abc 时,bc 中最后⾯的 c 会发⽣回溯,以便可以使⽤组外的 c 来使匹配成功。
(?#text)⽤于注释。text 的内容会被忽略。
语法实例
1、基本字符匹配
例如搜索city表中 Population 列包含'1000'的所有信息,并按照 ID 升序排序。
SELECT *
FROM city
WHERE Population REGEXP '1000'
ORDER BY ID;
搜索city表中 Population 列包含'000'的所有信息,并按照 ID 升序排序。
SELECT *
FROM city
WHERE Population REGEXP '.000'
ORDER BY ID;
注意:这⾥的点(.)表⽰匹配任意⼀个字符,例如,1000,2000,3000等都匹配且返回。
2、进⾏ OR (使⽤竖线(|)符号表⽰)匹配(为搜索多个串之⼀)
例如搜索city表中 Population 列包含 '1000' 或 '2000' 的所有信息,并按照ID升序排序。
SELECT *
FROM city
WHERE Population REGEXP '1000|2000'
ORDER BY ID;
注意:多个 OR 条件可以并⼊单个正则表达式,例如 '1000|2000|3000' 将匹配1000或2000或3000.
3、匹配⼏个字符之⼀(匹配任何单⼀字符,使⽤符号中括号([ ]))
例如搜索city表中 Population 列包含 '1000' 或 '2000' 或 '3000'的所有信息,并按照ID升序排序。
SELECT *
FROM city
WHERE Population REGEXP '[123]000'
ORDER BY ID;
注意:[ ] 是另⼀种形式的 OR 语句,事实上,[123]000 为 [1|2|3]000 的缩写(与 '1000|2000|3000'要⼀个意思)。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。