正则表达式

正则表达式是用来匹配文本的特殊的串(字符集合)

如果你想从一个文本文件中提取电话号码,可以使用正则表达式

如果你需要查找名字中间有数字的所有文件,可以使用一个正则表达式

如果你想在一个文本块中找到所有重复的单词,可以使用一个正则表达式

如果你想替换一个页面中的所有URL为这些 URL的实际HTML链接, 也可以使用一个正则表达式(对于最后这个例子,或者是两个正则表达式)

正则表达式通过正则表达式语言来建立


使用 MySQL 正则表达式

MySQL 用 WHERE 子句对正则表达式提供了初步的支持,允许指定正则表达式,过滤 SELECT 检索出的数据


基本字符匹配

SELECT prod_name FROM products
WHERE prod_name REGEXP '1000'
ORDER BY prod_name;

如上述代码,检索列 prod_name 包含文本 1000 的所有行

ip mysql 正则表达式 在mysql中使用正则表达式_正则表达式

除了关键字 LIKEREGEXP 替代外,这个语句看上去非常像使用 LIKE 的语句
它告诉 MySQL :REGEXP 后所跟的东西作为正则表达式处理(与文字正文 1000 匹配的一个正则表达式)

再看一个例子

SELECT prod_name FROM products
WHERE prod_name REGEXP '.000'
ORDER BY prod_name;

ip mysql 正则表达式 在mysql中使用正则表达式_数据库_02

这里使用了正则表达式 .000

. 是正则表达式语言中一个特殊的字符,表示匹配任意一个字符

因此,1000 和 2000 都匹配并返回

再看一个使用 LIKE 的语句

SELECT prod_name FROM products
WHERE prod_name LIKE '1000'
ORDER BY prod_name;

ip mysql 正则表达式 在mysql中使用正则表达式_ip mysql 正则表达式_03

可以发现,相比之前使用 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;

ip mysql 正则表达式 在mysql中使用正则表达式_数据库_04

语句中使用了正则表达式 1000|2000| 是正则表达式的 OR 操作符,多个 OR 条件可以并入单个正则表达式


匹配几个字符之一

如果想匹配特定的字符,可以通过指定一组用 [] 括起来的字符完成

SELECT prod_name FROM products
WHERE prod_name REGEXP '[123] Ton'
ORDER BY prod_name;

ip mysql 正则表达式 在mysql中使用正则表达式_正则表达式_05

使用正则表达式 [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;

ip mysql 正则表达式 在mysql中使用正则表达式_sql_06

如果没有 [] ,MySQL 会假定 123 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;

ip mysql 正则表达式 在mysql中使用正则表达式_mysql_07


匹配特殊字符

正则表达式语言由具有特定含义的特殊字符构成,如 -[].|

如果想要匹配这些特殊字符,则必须用 \\ 为前导
\\- 表示查找 -\\. 表示查找 .

如下示例:

SELECT vend_name FROM vendors
WHERE vend_name REGEXP '\\.'
ORDER BY vend_name;

ip mysql 正则表达式 在mysql中使用正则表达式_正则表达式_08

这种处理就是所谓的 转义(escaping)
正则表达式内具有特殊意义的所有字符都必须以这种方式转义

\\ 也用来引用元字符(具有特殊含义的字符)

ip mysql 正则表达式 在mysql中使用正则表达式_数据库_09

为了匹配 \ ,则需要使用 \\\

多数正则表达式实现使用单个反斜杠转义特殊字符,以便能使用这些字符本身,但是 MySQL 使用两个反斜杠(MySQL 自己解释一个,正则表达式解释一个)


匹配字符类

存在找出你自己经常使用的数字、所有字母字符或所有数字字母字符的匹配
为了更方便工作,可以使用预定义的字符集,称为 字符类(character class)

ip mysql 正则表达式 在mysql中使用正则表达式_mysql_10


匹配多个实例

有时候需要对匹配的数目进行更强的控制;例如,可能需要寻找所有的数,不管数中包含多少数字,或者可能想要寻找一个单词并且还能够适应一个尾随的 s (如果存在)

这些需要使用正则表达式重复元字符来完成

ip mysql 正则表达式 在mysql中使用正则表达式_数据库_11

示例1:

SELECT prod_name FROM products
WHERE prod_name REGEXP '\\([0-9] sticks?\\)'
ORDER BY prod_name;

ip mysql 正则表达式 在mysql中使用正则表达式_ip mysql 正则表达式_12

正则表达式 \\([0-9] sticks?\\) 含义:
\\( 匹配 ([0-9] 匹配任意数字,sticks? 匹配 sticksticks (s 后的 使 s 可选,因为 匹配它前面的任何字符的 0 次或者 1 次出现),\\) 匹配 )+

示例2:

SELECT prod_name FROM products
WHERE prod_name REGEXP '[[:digit:]]{4}'
ORDER BY prod_name;

ip mysql 正则表达式 在mysql中使用正则表达式_正则表达式_13

[:digit:] 匹配任意数字,因而它为数字的一个集合,{4} 确切地要求它前面的字符(任意数字)出现 4 次,所以 [[:digit:]]{4} 匹配连在一起的任意 4 位数字


定位符

为了匹配特定位置的文本,需要使用定位元字符

ip mysql 正则表达式 在mysql中使用正则表达式_sql_14

例如,如果想要找出以一个数(包括以小数点开始的数)开始的所有产品,简单搜索 [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;

ip mysql 正则表达式 在mysql中使用正则表达式_ip mysql 正则表达式_15

在集合中([] 内),可以 ^ 否定该集合;否则,则用来指串的开始处

利用定位符,通过使用 ^ 开始每个表达式,使用 $ 结束每个表达式,可以使 REGEXP 的作用与 LIKE 一样