第九章
第九章 用正则表达式进行搜索
正则表达式简单介绍
正则表达式是用来匹配文本的特殊的串(字符集合)。
正则表达式用正则表达式语言来建立,正则表达式语言是用来完成刚讨论的所有工作以及更多工作的一种特殊语言。与任意语言一样,正则表达式具有你必须学习的特殊的语法和指令。
基本字符匹配
下面的语句检索列prod_name包含文本1000的所有行:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000'
ORDER BY prod_name;
简单匹配.png
分析:除关键字LIKE被REGEXP取代外,这条语句看上去非常像使用LIKE的语句。它告诉MySQL:REGEXP后跟的东西作为正则表达式(与正文1000匹配的一个正则表达式)处理。
特殊字符的匹配
SELECT prod_name
FROM products
WHERE prod_name REGEXP '.000'
ORDER BY prod_name;
.特殊字符.png
分析:这里使用了正则表达式.000。.是正则表达式中一个特殊的字符。它表示匹配任意一个字符,因此,1000和2000都匹配并且返回。
LIKE 和REGEXP的区别
SELECT prod_name
FROM products
WHERE prod_name like '1000'
ORDER BY prod_name;
SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000'
ORDER BY prod_name;
如果执行上述两条语句,会发现第一条不返回数据,第二条返回一行。
因为LIKE匹配整个列。如果匹配的文本在列值中出现,LIKE将不会找到它,相应的行也不被返回(除非通配符)。而REGEXP在列值内进行匹配,如果匹配的文本在列值中出现,REGEXP将会找到它,相应的行将会返回。这是一个非常重要的差别。
匹配不分大小写,如果需要,使用BINARY
例如:
WHERE prod_name REGEXP BINARY 'JetPack .1000'
进行OR匹配
SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000 | 2000'
ORDER BY prod_name;
OR匹配.png
分析:| 为正则表达式OR的操作符。它表示匹配其中一个,因此1000和2000都匹配并返回。
使用 | 从功能上类似于在SELECT语句中使用OR语句,多个OR条件可并入单个正则表达式。
如 '1000|2000|3000'将匹配1000或2000或3000
匹配几个字符之一
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[123] Ton'
ORDER BY prod_name;
匹配结果.png
分析:这里使用了正则表达式[123] Ton。[123]定义一组字符,它的意思是匹配1或2或3,因此1 Ton和2 Ton都返回(没有3 Ton)。
通过上述分析可知,[ ]是另一中形式的OR语句。事实上[123] Ton为[1|2|3] Ton 的缩写。
字符集合也可以被否定,即它们将匹配指定字符外的任何东西。为否定一个字符,在集合的开始处放置一个^即可。因此尽管[123]匹配字符1、2或者3,但[^123]却匹配除这些字符以外的任何东西。
匹配范围
集合可用来定义匹配一个或者多个字符。例如下面将匹配0-9的字符[0123456789]
为了简化这种类型的集合,使用-来定义一个范围。所以[0123456789]等同于[0-9]。不限范围和数值型。如:[0-3] [6-9] [a-z] 都是正确的。
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[1-5] Ton'
ORDER BY prod_name;
范围匹配.png
匹配特殊字符
正则表达式语言由具有特定含义的特殊字符构成。.、[]、|和-等,还有其他一些字符。
例如要找出包含 . 字符的值
SELECT vend_name
FROM vendors
WHERE vend_name REGEXP '\\.'
ORDER BY prod_name;
特殊字符.匹配结果.png
分析:为了匹配特殊字符,必须用\\为前导。\-表示查找-,\.表示查找.这种处理就是所谓的转义(escaping),正则表达式内具有特殊意义的所有字符都必须以这种方式转义。这包括 . | [ ]以及迄今为止使用过的其他特殊字符。
\\也用来引用元字符(具有特殊含义的字符),如表9-1所示。
表9-2 字符类
| 元 字 符 | 说 明 |
|---|---|
| \\f | 换页 |
| \\n | 换行 |
| \\r | 回车 |
| \\t | 制表 |
| \\v | 纵向制表 |
\和\\?
多数正则表达式使用单个反斜杠来转义特殊字符,以便能使用这些字符本身。但MySQL要求使用两个反斜杠\\(MySQL自己解释一个,正则表达式库解释一个)。
匹配字符类
表9-2 字符类
| 类 | 说 明 |
|---|---|
| [:alnum:] | 任意字母和数字(同[a-zA-Z0-9]) |
| [:alpha:] | 任意字符(同[a-zA-Z]) |
| [:blank:] | 空格和制表(同[\\t]) |
| [:cntrl:] | ASCII控制字符(ASCII 0到31和127) |
| [:digit:] | 任意数字(同[0-9]) |
| [:graph:] | 与[:print:]相同,但不包括空格 |
| [:lower:] | 任意小写字母(同[a-z]) |
| [:print:] | 任意可打印字符 |
| [:punct:] | 既不在[:alnum:]又不在[:cntrl:]中的任意字符 |
| [:space:] | 包括空格在内的任意空白字符(同[\\f\\n\\r\\t\\v]) |
| [:upper:] | 任意大写字母(同[A-Z]) |
| [:xdigit:] | 任意十六进制数字(同[a-fA-F0-9]) |
匹配多个实例
表9-3重复元字符
| 元 字 符 | 说 明 |
|---|---|
| * | 0个或多个匹配 |
| + | 1个或多个匹配(等于{1,}) |
| ? | 0个或1个匹配(等于{0,1}) |
| {n} | 指定数目的匹配 |
| {n,} | 不少于指定数目的匹配 |
| {n,m} | 匹配数目的范围(m不超过255) |
下面举几个例子
SELECT prod_name
FROM products
WHERE prod_name REGEXP '\\([0-9] sticks?\\)'
匹配多个实例.png
分析:正则表达式\\([0-9] sticks?\\)中,\\(匹配),[0-9]匹配任何数字(这个例子中为1和5),stack?匹配stack和stacks(s后的?使s可选,因为?匹配它前面的字符0次或者1次出现),\\)匹配)。没有?,匹配stack和stacks比较困难。
匹配连在一起的4个数字
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[[:digit:]] {4}'
ORDER BY prod_name;
匹配连在一起的4个数字.png
分析:如前所述,[:digit:]匹配任意数字,所以它为数字的一个集合。{4}确切的要求前面的字符(任意数字)出现4次,所以连在一起[[:digit:]] {4}匹配连在一起的任意4个数字。
上述代码还可以替换为
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[0-9][0-9][0-9][0-9]'
ORDER BY prod_name;
定位符
表9-4 定位元字符
| 元字符 | 说 明 |
|---|---|
| ^ | 文本的开始 |
| $ | 文本的结束 |
| [:<:] | 词的开始 |
| [:>:] | 词的结尾 |
如:找出以一个数(包括以小数点开始的数)开始的新的所有产品
SELECT prod_name
FROM products
WHERE prod_name REGEXP '^[0-9\\.]'
ORDER BY prod_name;
匹配结果.png
分析:^匹配字符串的开始,^[0-9\\.]只在.或者任意数字为串中第一个字符时才匹配它们。
第九章小结
本章介绍了正则表达式的基础知识,学习了如何在MySQL的SELECT语句中通过REGEXP关键字使用它们。
本章的难点在于:匹配特殊字符、匹配字符类、匹配多个实例、定位符这几个小节的内容表多且碎,把相应的表背过了多写多理解就容易写出来。








网友评论