文章目录
- 1. 概述
- 2. 基本字符匹配
- 3.LIKE关键字与正则表达式的区别
- 4.进行OR匹配
- 5.匹配几个字符之一
- 6.匹配范围
- 7.匹配特殊字符
- 8.匹配多个实例
- 9.定位符
1. 概述
正则表达式用来匹配更加复杂的查询条件,例如你想从文件中提取电话号码,想从查找名字中间有数字的所有文件,甚至在一个文本块中查找所有重复的字符,都可以使用正则表达式完成;
但是在此处,我们只介绍MySql中正则表达式的使用,具体关于正则表达式的内容,大家可以自行学习;
MySql 用WHERE子句对正则表达式提供了初步的支持,允许你指定正则表达式,过滤SELECT查询出的数据;
2. 基本字符匹配
我们尝试查询列 prod_name 包含文本“1000”的所有行,并按照 prod_name 进行排序:
输入:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000'
ORDER BY prod_name;
输出:
上述的查询语句除了关键字由 LIKE 变为 REGEXP 外,其它都很像使用LIKE关键字查询的语句,它告诉 MySql :REGEXP 后所跟的所有东西作为正则表达式处理;
上面的例子使用正则表达式并没有带来什么好处,反而可能会影响查询性能,不过,我们可以参考下面的例子:
输入:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '.000'
ORDER BY prod_name;
输出:
这里使用了正则表达式.000。. 是正则表达式中一个特殊的字符,我们在JAVA基础中曾经讲过,其表示匹配任意一个字符,因此1000与2000都匹配且返回;
3.LIKE关键字与正则表达式的区别
上面的特殊案例也可以使用LIKE关键字来实现,但是要使用通配符来完成:
输入:
SELECT prod_name
FROM products
WHERE prod_name LIKE '%000'
ORDER BY prod_name;
输出:
但是如果比较下列的俩个语句就会发现其区别:
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将不会找到它,相应的行也不会被返回。而GEGEXP在列值中进行匹配,如果被匹配的文本在列值中出现,REGEXP会找到它,相应的行将会被返回。
4.进行OR匹配
为了搜索俩个值之一,使用 | ,如:
输入:
SELECT prod_name
FROM products
WHERE prod_name LIKE '1000|2000'
ORDER BY prod_name;
输出:
语句使用了正则表达式1000|2000。 | 为正则表达式的OR操作符,其表示匹配其中之一,因此1000和2000都匹配并返回。
使用 | 从功能上来说类似于在SELECT语句中使用OR语句,多个OR条件可并入单个正则表达式。
5.匹配几个字符之一
如果我们只想匹配特定的字符,那么可以使用中括号 [ ] 将特定字符括起来进行正则表达式搜索,如:
输入:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[123] ton'
ORDER BY prod_name;
输出:
[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,而不是1 ton 或2 ton 或3 ton,除非把字符 | 括在一个集合中,否则它将用于整个串;
并且字符集合也可以被否定,即,他们将匹配除指定字符外的任何东西,为了否定一个字符,需要在集合的开始位置使用 ^ 字符,[123] 匹配字符1或2或3,但是[^123] 却匹配除这些字符外的任何东西。
6.匹配范围
集合可以用来匹配范围,如:
[0123456789]
为了简化这种类型的集合,可以使用-来定义一个范围,下面的式子与上面的式子功能一样:
[0-9]
范围不限于完整的集合,[1-3] 和 [6-9] 也是合法的范围。此外,范围不一定只是数值,[a-z] 匹配任意字母,如:
输入:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[1-5] ton'
ORDER BY prod_name;
输出:
7.匹配特殊字符
正则表达式语言具有特定含义的特殊字符构成。假如我们需要匹配特殊字符 . 该怎么输入呢?
输入:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '.'
ORDER BY prod_name;
输出:
这并不是我们期望的结果,因为 . 在正则表达式中表示匹配任何一个字符,所以全部结果都会被返回看,为了匹配特殊字符,我们必须使用 \ 为前缀,\- 表示查找-,\. 表示查找 . ;
其实\也是一种特殊字符,其是转义字符,如果你想匹配 \ ,那么此时你需要输入 \\;
8.匹配多个实例
目前使用的所以正则表达式都试图匹配单次出现。如果存在一个匹配,该行被查询到,如果不存在,查不到任何结果。但有时需要对匹配数目进行更强的控制。例如,你可能需要寻找所有的数,不管数中包含多少数字,或者你可能需要查找一个单词,并且还能够适应一个尾随的s等等,如:
元字符 | 说明 |
---|---|
* | 0个或多个匹配 |
+ | 1个或多个匹配 |
? | 0个或1个匹配 |
{n} | 指定数目的匹配 |
{n,} | 不少于指定数目的匹配 |
{n,m} | 匹配数目的范围(m不超过255) |
输入:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '\\([0-9] sticks?\\)'
ORDER BY prod_name;
输出:
\\( 匹配 ( ;
[0-9] 匹配任意数字;
sticks?匹配stick和sticks,s后的?使s可选,?匹配它前面的字符的0次或1次出现;
\\)匹配 ) ;
下方是另一个例子,我们打算匹配连在一起的4位数字:
输入:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[0-9]{4}'
ORDER BY prod_name;
输出:
[0-9] 匹配任意数字;
{4} 表示它前面的数字出现4次;
9.定位符
目前所有的例子都是匹配一个字符串中任意位置的文本。为了匹配特定位置的文本,需要使用定位符:
元字符 | 说明 |
---|---|
^ | 文本的开始 |
$ | 文本的结尾 |
[[:<:]] | 词的开始 |
[[:>:]] | 词的结尾 |
例如,我们想查找一个数开始的所有产品,简单搜索[0-9\.]肯定不行,因为它将在字符串任意位置进行查找,解决办法就是使用^定位符:
输入:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '^[0-9\\.]'
ORDER BY prod_name;
输出:
匹配串的开始,因此只在.或数字为第一个字母时才匹配它们,没有则要多检索出4行数据。
注意区别,^在集合中使用用来否定集合,否则用来指字符串的开始处;