《MySQL必知必會》學習筆記——第九章(正則表示式)
文章目錄
前文連線:
《MySQL必知必會》——書中表的生成
《MySQL必知必會》——第三章(瞭解資料庫和表) 關鍵詞:USE、SHOW
《MySQL必知必會》——第四章(檢索資料) 關鍵詞:SELECT
《MySQL必知必會》——第五章(排序檢索資料) 關鍵詞:ORDER BY
《MySQL必知必會》——第六章(過濾資料) 關鍵詞:WHERE
《MySQL必知必會》——第七章(資料過濾) 關鍵詞:WHERE、AND、OR、IN
《MySQL必知必會》——第八章(用萬用字元過濾)關鍵詞:LIKE % _
第6、7、8章講述了基本的資料過濾操作,但隨著過濾資料複雜性的提升,WHERE子句的複雜性也會越來越大!這時我們就可以使用正則表示式就處理相關的資料!
9.1 正則表示式
正則表示式:
- 是用來匹配文字的特殊字串。如:本文中電話號碼、網址、人名、地點等等的匹配,都可以去使用正則表示式去做
9.2 MySQL中正則表示式的使用
正則表示式可以去匹配文字中的某些片段(網址、電話等等),而MySQL中的 WHERE子句
9.2.1 基本字元匹配
我們在 products表 中舉例:
先看看錶中的基本資訊:
USE test;
SELECT * FROM products;
- 若我們找 prod_name列 中包含 1000 的行:
# like: % 表示匹配任意字元
SELECT prod_name FROM products where prod_name like '%1000%';
# 正則表示式 RegExp: '1000'表示匹配文字中含有'1000'的資料
SELECT prod_name FROM products where prod_name RegExp '1000';
上述兩種的結果是一致的
- 若我們找 prod_name列 中包含 000 的行:
# like: % 表示匹配任意字元
SELECT prod_name FROM products where prod_name like '%000';
# 正則表示式: . 表示匹配任意字元
SELECT prod_name FROM products where prod_name RegExp '.000';
上述兩種的結果是一致的
注意:
- MySQL正則表示式匹配是 不區分大小寫 的,若要區分大小寫可以使用 BINARY關鍵詞
- 如: WHERE prod_name RegExp BINARY ‘要匹配的文字’
9.2.2 進行OR匹配
正則表示式中OR操作符為: | ,我們舉例看看:
# 匹配文字中包含 1000 或者 2000 的資料
SELECT prod_name FROM products where prod_name RegExp '1000|2000';
拓展:
- 若是兩個以上的OR操作:可以用:1000|2000|3000 等等
9.2.3 匹配幾個字元之一
匹配 任意單一字元 : [] , 我們舉例看看:
# 匹配文字中包含 1 或 2 或 3 的資料
SELECT prod_name FROM products where prod_name RegExp '[123]';
# 我們也可以使用OR來表示
SELECT prod_name FROM products where prod_name RegExp '1|2|3';
上述兩種表達的結果是一致的:
拓展:
- 我們可以使用: ^ ,匹配除了指定字元之外的任意字元
- where 列名 regexp ‘[^2]’ :表示除了2之外的任意字元
9.2.4 匹配範圍
使用集合來匹配一和或多個字元,如使用 [0123456789] 來匹配0到9任意的數字,為了簡化上述的表達,我們可以使用 - ,如:[0-9]
# 匹配文字中包含 1 到 5的任意資料
SELECT prod_name FROM products where prod_name RegExp '[1-5]';
當然,我們可以表示用: [a-z] 表示任意字元的範圍
9.2.5 匹配特殊字元
上面我們學習了很多的特殊字元,如:. [ ] | - 等,要是我們需要匹配這些特殊字元應該怎麼辦呢?
我們需要在特殊字元前面加上 \ \ ,進行轉義,我們舉例看看:
# . 是匹配任意字元,vend_name 所有的行都將返回
SELECT vend_name FROM vendors WHERE vend_name RegExp '.';
# 我們加上轉義符 \\,這樣就可以匹配 '.'
SELECT vend_name FROM vendors WHERE vend_name RegExp '\\.';
注意:
- 正則表示式一般用 \ 來進行轉義, 而MySQL使用 \ 來進行轉義
9.2.6 匹配字元類
下面列一些經常會用到的匹配模式:
類 | 說明 |
---|---|
[:alnum:] | 任意字母和數字(同 [a-zA-Z0-9]) |
[:alpha:] | 任意字元(同[a-zA-Z]) |
[:blank:] | 空格和製表(同 [\t]) |
[:cntrl:] | ASCII控制字元 (ASCII 0 到 31和127) |
[:digit:] | 任意數字(同 [0-9]) |
[:print:] | 任意可列印字元 |
[:graph:] | 與[:print:]相同,但是不包括空格 |
[:lower:] | 任意小寫字母(同 [a-z]) |
[:upper:] | 任意大寫字母(同 [A-Z]) |
[:punct:] | 即不在 [:alnum:] 又不在 [:cntrl:] 中的任意字元 |
[:space:] | 包括空格在內的任意空白字元(同 [\ \f \ \n \ \r \ \t \ \v]) |
[:xdigit:] | 任意十六進位制數字(同 [a-zA-Z0-9]) |
9.2.7 匹配多個例項
有時我們不僅僅匹配單一例項,我們需要匹配多個例項,這時我們有以下操作:
元字元 | 說明 |
---|---|
* | 0個或多個匹配 |
+ | 1個或多個匹配(等同於 {1,}) |
? | 0個或1個匹配(等同於 {0,1}) |
{n} | 指定數目n的匹配 |
{n, } | 不少於指定數目n的匹配 |
{n, m} | 匹配數目的範圍(m不超過255) |
我們舉例看看上面的操作如何使用:
SELECT prod_name FROM products where prod_name RegExp '[0-9] sticks?';
解釋:’[0-9] sticks?’ :
- [0-9]:匹配0-9之間的任意數字
- sticks?:其中的 '?'是指其前面的字元’s’有0個或1個,這樣就是匹配 stick 或者 sticks
SELECT prod_name FROM products where prod_name RegExp '[:digit:]{4}';
解釋:’[:digit:]{4}’
- [:digit:]:匹配 0-9 的任意數字
- {4}:要求其前面的字元出現4次
當然上面的操作,我們也可以使用下面這種寫法:
SELECT prod_name FROM products where prod_name RegExp '[0-9][0-9][0-9][0-9]';
9.2.8 定位符
上面提到的都是匹配一個串中任意位置的文字,為了匹配特定位置的文字,我們使用下表中的定位符:
元字元 | 說明 |
---|---|
^ | 文字的開始 |
$ | 文字的末尾 |
[[:<:]] | 詞的開始 |
[[:>:]] | 詞的結尾 |
我們舉例看看:
# 找出以數字開頭的資料
SELECT prod_name FROM products where prod_name RegExp '^[0-9].';
解釋: ’ ^ [0-9]. ’
- ^:表示文字的開始
- [0-9]:表示匹配數字
- . :表示匹配任意字元
注意:
- ^:在集合[]中,表示否定集合中的內容;在集合外,表示文字的開頭
- RegExp匹配文字中的子串,LIKE匹配整個文字,我們在使用RegExp時,通過指定開頭^和文字的末尾$,就可以使得RegExp和LIKE用法一致
9.2.9 測試正則表示式
我們想要測試正則表示式是否正確時,可以不用資料庫,直接使用SELECT語句,若返回0說明沒有匹配上,返回1說明匹配上!
SELECT 'HELLO' RegExp '[a-z]';
SELECT 'HELLO' RegExp '[0-9]';
總結:
- SELECT 列名 FROM 表名 WHERE 列名 RegExp 正則表示式:匹配特定的文字