0%

《MySQL必知必会》读书笔记 第九章 用正则表达式进行搜索

正则表达式

随着过滤条件的复杂性的增加,WHERE子句本身的复杂性也有必要增加。

这也就是正则表达式变得有用的地方。正则表达式是用来匹配文本的特殊的串(字符集合)。

所有种类的程序设计语言、文本编辑器、操作系统等都支持正则表达式。

使用MySQL正则表达式

MySQL用WHERE子句对正则表达式提供了初步的支持。

MySQL仅支持多数正则表达式实现的一个很小的子集。

MySQL中的正则表达式匹配(自版本3.23.4后)不区分大小写(即,大写和小写都匹配)。为区分大小写,可使用BINARY关键字,如WHERE prod_name REGEXP BINARY ‘JetPack .000’。

可以在不使用数据库表的情况下用SELECT来测试正则表达式。REGEXP检查总是返回0(没有匹配)或1(匹配)。如SELECT ‘hello’ REGEXP ‘[0-9]’会返回0

基本字符匹配

检索列prod_name包含文本1000的所有行:

1
2
3
4
SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000'
ORDER BY prod_name;

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

1
2
3
4
SELECT prod_name
FROM products
WHERE prod_name REGEXP '.000'
ORDER BY prod_name;

进行OR匹配

为搜索两个串之一,使用|字符。

1
2
3
4
SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000|2000'
ORDER BY prod_name;

匹配几个字符之一

要匹配多个特定的字符,可以将字符用一组用[和]括起来

1
2
3
4
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[123] Ton'
ORDER BY prod_name

字符集合也可以被否定,在集合的开始处放置一个^即可,比如[^123]匹配除这些字符外的任何东西。

匹配范围

[0-9]等同于[123456789],[a-z]匹配任意字母字符。

1
2
3
4
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[1-5] Ton'
ORDER BY prod_name;

匹配特殊字符

为了匹配特殊字符,必须用\为前导。\-表示查找-,\.表示查找.。

1
2
3
4
SELECT vend_name
FROM vendors
WHERE vend_name REGEXP '\\.'
ORDER BY vend_name;

匹配字符类

预定义的字符集,称为字符类(character class)

  • [: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])

匹配多个实例

有时需要对匹配的数目进行更强的控制,这可以用正则表达式重复元字符来完成

  • * 0个或多个匹配
  • + 1个或多个匹配(等于{1,})
  • ? 0个或1个匹配(等于{0,1})
  • {n} 指定数目的匹配
  • {n,} 不少于指定数目的匹配
  • {n,m} 匹配数目的范围(m不超过255)

使用sticks?匹配stick和sticks:

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

匹配连在一起的4位数字:

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

定位符

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

  • ^ 文本的开始
  • $ 文本的结尾
  • [[:<:]] 词的开始
  • [[:>:]] 词的结尾

^有两种用法。在集合中(用[和]定义),用它来否定该集合,否则,用来指串的开始处。

检索以一个数(包括以小数点开始的数)开始的所有产品

1
2
3
4
SELECT prod_name
FROM products
WHERE prod_name REGEXP '^[0-9\\.]'
ORDER BY prod_name;