正则表达式
正则表达式是用来匹配文本的特殊的串(字符集合)
如果你想从一个文本文件中提取电话号码,可以使用正则表达式
如果你需要查找名字中间有数字的所有文件,可以使用一个正则表达式
如果你想在一个文本块中找到所有重复的单词,可以使用一个正则表达式
如果你想替换一个页面中的所有URL为这些 URL的实际HTML链接, 也可以使用一个正则表达式(对于最后这个例子,或者是两个正则表达式)
正则表达式通过正则表达式语言来建立
使用 MySQL 正则表达式
MySQL 用 WHERE
子句对正则表达式提供了初步的支持,允许指定正则表达式,过滤 SELECT
检索出的数据
基本字符匹配
SELECT prod_name FROM products
WHERE prod_name REGEXP '1000'
ORDER BY prod_name;
如上述代码,检索列 prod_name 包含文本 1000 的所有行
除了关键字 LIKE
被 REGEXP
替代外,这个语句看上去非常像使用 LIKE
的语句
它告诉 MySQL :REGEXP
后所跟的东西作为正则表达式处理(与文字正文 1000 匹配的一个正则表达式)
再看一个例子
SELECT prod_name FROM products
WHERE prod_name REGEXP '.000'
ORDER BY prod_name;
这里使用了正则表达式 .000
.
是正则表达式语言中一个特殊的字符,表示匹配任意一个字符
因此,1000 和 2000 都匹配并返回
再看一个使用 LIKE
的语句
SELECT prod_name FROM products
WHERE prod_name LIKE '1000'
ORDER BY prod_name;
可以发现,相比之前使用 GEREXP
返回一行数据,使用 LIKE
不会返回数据
LIKE
匹配整个列,如果被匹配的文本在列值中出现,LIKE
将不会找到它,相应的行也不会被返回(除非使用通配符)
GEREXP
在列值内进行匹配,如果被匹配的文本在列值中出现,GEREXP
将会找到它,相应的行将被返回如果
GEREXP
想要匹配整个列值(从而起到和LIKE
)一样的作用,需要使用^
和$
定位符(anchor)MySQL 中的正则表达式匹配不区分大小写,为了区分大小写可以使用
BINARY
关键字,如,WHERE prod_name REGEXP BINARY 'JetPack .0000'
进行 OR
匹配
为了检索两个串之一(或者为这个串,或者为另一个串),使用 |
SELECT prod_name FROM products
WHERE prod_name REGEXP '1000|2000'
ORDER BY prod_name;
语句中使用了正则表达式 1000|2000
,|
是正则表达式的 OR
操作符,多个 OR
条件可以并入单个正则表达式
匹配几个字符之一
如果想匹配特定的字符,可以通过指定一组用 []
括起来的字符完成
SELECT prod_name FROM products
WHERE prod_name REGEXP '[123] Ton'
ORDER BY prod_name;
使用正则表达式 [123] Ton
;[123]
定义一组字符,它的意思是匹配 1 或者 2 或者 3,因此可以匹配 1 ton 和 2 ton
[]
也是另一种形式的 OR
语句;[123] Ton
等价于 [1|2|3] Ton
;注意,需要用 []
来定义 OR
语句查找什么
SELECT prod_name FROM products
WHERE prod_name REGEXP '1|2|3 Ton'
ORDER BY prod_name;
如果没有 []
,MySQL 会假定 1
或 2
或 3 Ton
三种情况
除非把字符串 |
括在一个集合中,否则将应用于整个串
字符串集合也可以被否定,即,它们将匹配除指定字符外的任何东西
为否定一个字符集,在集合的开始处需要一个
^
[123]
会匹配字符1、2或者3,但是[^123]
却匹配除这些字符外的任何东西
匹配范围
集合可以用来定义要匹配的一个或多个字符;例如, [123456789]
将匹配数字0到9,为了简化这种类型的集合,可以使用 -
来定义一个范围 [0-9]
范围不限于完整的集合,
[1-3]
和[6-9]
也是合法的范围此外,范围也不一定只是数值,
[a-z]
匹配任意字母字符
示例如下:
SELECT prod_name FROM products
WHERE prod_name REGEXP '[1-5] Ton'
ORDER BY prod_name;
匹配特殊字符
正则表达式语言由具有特定含义的特殊字符构成,如 -
、 []
、 .
、 |
如果想要匹配这些特殊字符,则必须用 \\
为前导\\-
表示查找 -
\\.
表示查找 .
如下示例:
SELECT vend_name FROM vendors
WHERE vend_name REGEXP '\\.'
ORDER BY vend_name;
这种处理就是所谓的 转义(escaping)
正则表达式内具有特殊意义的所有字符都必须以这种方式转义
\\
也用来引用元字符(具有特殊含义的字符)
为了匹配
\
,则需要使用\\\
多数正则表达式实现使用单个反斜杠转义特殊字符,以便能使用这些字符本身,但是 MySQL 使用两个反斜杠(MySQL 自己解释一个,正则表达式解释一个)
匹配字符类
存在找出你自己经常使用的数字、所有字母字符或所有数字字母字符的匹配
为了更方便工作,可以使用预定义的字符集,称为 字符类(character class)
匹配多个实例
有时候需要对匹配的数目进行更强的控制;例如,可能需要寻找所有的数,不管数中包含多少数字,或者可能想要寻找一个单词并且还能够适应一个尾随的 s (如果存在)
这些需要使用正则表达式重复元字符来完成
示例1:
SELECT prod_name FROM products
WHERE prod_name REGEXP '\\([0-9] sticks?\\)'
ORDER BY prod_name;
正则表达式
\\([0-9] sticks?\\)
含义:\\(
匹配(
,[0-9]
匹配任意数字,sticks?
匹配stick
和sticks
(s 后的?
使 s 可选,因为?
匹配它前面的任何字符的 0 次或者 1 次出现),\\)
匹配)
+
示例2:
SELECT prod_name FROM products
WHERE prod_name REGEXP '[[:digit:]]{4}'
ORDER BY prod_name;
[:digit:]
匹配任意数字,因而它为数字的一个集合,{4}
确切地要求它前面的字符(任意数字)出现 4 次,所以 [[:digit:]]{4}
匹配连在一起的任意 4 位数字
定位符
为了匹配特定位置的文本,需要使用定位元字符
例如,如果想要找出以一个数(包括以小数点开始的数)开始的所有产品,简单搜索 [0-9\\.]
或者 [[:digit:]\\.]
不行,因为它将在文本内任意位置查找匹配,这时就需要使用定位符 ^
比较下面两个语句:
SELECT prod_name FROM products
WHERE prod_name REGEXP '^[0-9\\.]'
ORDER BY prod_name;
SELECT prod_name FROM products
WHERE prod_name REGEXP '[0-9\\.]'
ORDER BY prod_name;
在集合中(
[]
内),可以^
否定该集合;否则,则用来指串的开始处利用定位符,通过使用
^
开始每个表达式,使用$
结束每个表达式,可以使REGEXP
的作用与LIKE
一样