之前我要查找數據都是使用like後來發現mysql中也有正則表達式了而且感受性能要好於like,下面我來給你們分享一下mysql REGEXP正則表達式使用詳解,但願此方法對你們有幫助。php
在開始這個話題以前咱們首先來作一個小實驗,比較一下REGEXP和Like他們兩個哪一個效率高,若是效率過低,咱們就沒有必要作過多的研究了,實驗的代碼以下:html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?php
Require(
"config.php"
);
//函數:計時函數
//用法:Echo Runtime(1);
Function Runtime(
$mode
=0){
Static
$s
;
IF(!
$mode
){
$s
=microtime();
Return;
}
$e
=microtime();
$s
=
Explode
(
" "
,
$s
);
$e
=
Explode
(
" "
,
$e
);
Return Sprintf(
"%.2f ms"
,(
$e
[1]+
$e
[0]-
$s
[1]-
$s
[0])*1000);
}
//如下測試結果爲2300 ms至2330 ms之間
For(
$i
=0;
$i
<10000;
$i
++){
$Rs
=
$Mysql
->Get(
"SELECT * FROM `hotel` where address REGEXP '^連江縣|桃園市'"
);
}
//如下測試結果爲2300 ms至2330 ms之間
For(
$i
=0;
$i
<10000;
$i
++){
$Rs
=
$Mysql
->Get(
"SELECT * FROM `hotel` where address like '連江縣%' or address like '%桃園市%'"
);
}
Echo
Runtime(1);
|
實驗的結果很讓人驚喜,那就是他們兩個的效率幾乎差很少,上下浮動差不了幾十毫秒,那麼咱們就有必要對REGEXP作深刻研究了,由於他可以大大的縮短sql語句的長度.對於很長的查詢條件來講用這種查詢能夠很好的縮短sql長度.mysql
MySQL採用Henry Spencer的正則表達式實施,其目標是符合POSIX 1003.2。請參見附錄C:感謝。MySQL採用了擴展的版本,以支持在SQL語句中與REGEXP操做符一塊兒使用的模式匹配操做。請參見3.3.4.7節,「模式匹配」。git
在本附錄中,概括了在MySQL中可用於REGEXP操做的特殊字符和結構,並給出了一些示例。本附錄未包含可在Henry Spencer的regex(7)手冊頁面中發現的全部細節。該手冊頁面包含在MySQL源碼分發版中,位於regex目錄下的regex.7文件中。正則表達式
正則表達式描述了一組字符串。最簡單的正則表達式是不含任何特殊字符的正則表達式。例如,正則表達式hello匹配hello。sql
非平凡的正則表達式採用了特殊的特定結構,從而使得它們可以與1個以上的字符串匹配。例如,正則表達式hello|word匹配字符串hello或字符串word。數據庫
做爲一個更爲複雜的示例,正則表達式B[an]*s匹配下述字符串中的任何一個:Bananas,Baaaaas,Bs,以及以B開始、以s結束、並在其中包含任意數目a或n字符的任何其餘字符串。函數
對於REGEXP操做符,正則表達式可使用任何下述特殊字符和結構:性能
^
匹配字符串的開始部分。測試
mysql> SELECT 'fo\nfo' REGEXP '^fo$';
-> 0
mysql> SELECT 'fofo' REGEXP '^fo';
-> 1
$
匹配字符串的結束部分。
mysql> SELECT 'fo\no' REGEXP '^fo\no$';
-> 1
mysql> SELECT 'fo\no' REGEXP '^fo$';
-> 0
.
匹配任何字符(包括回車和新行)。
mysql> SELECT 'fofo' REGEXP '^f.*$';
-> 1
mysql> SELECT 'fo\r\nfo' REGEXP '^f.*$';
-> 1
a*
匹配0或多個a字符的任何序列。
mysql> SELECT 'Ban' REGEXP '^Ba*n';
-> 1
mysql> SELECT 'Baaan' REGEXP '^Ba*n';
-> 1
mysql> SELECT 'Bn' REGEXP '^Ba*n';
-> 1
a+
匹配1個或多個a字符的任何序列。
mysql> SELECT 'Ban' REGEXP '^Ba+n';
-> 1
mysql> SELECT 'Bn' REGEXP '^Ba+n';
-> 0
a?
匹配0個或1個a字符。
mysql> SELECT 'Bn' REGEXP '^Ba?n';
-> 1
mysql> SELECT 'Ban' REGEXP '^Ba?n';
-> 1
mysql> SELECT 'Baan' REGEXP '^Ba?n';
-> 0
de|abc
匹配序列de或abc。
mysql> SELECT 'pi' REGEXP 'pi|apa';
-> 1
mysql> SELECT 'axe' REGEXP 'pi|apa';
-> 0
mysql> SELECT 'apa' REGEXP 'pi|apa';
-> 1
mysql> SELECT 'apa' REGEXP '^(pi|apa)$';
-> 1
mysql> SELECT 'pi' REGEXP '^(pi|apa)$';
-> 1
mysql> SELECT 'pix' REGEXP '^(pi|apa)$';
-> 0
(abc)*
匹配序列abc的0個或多個實例。
mysql> SELECT 'pi' REGEXP '^(pi)*$';
-> 1
mysql> SELECT 'pip' REGEXP '^(pi)*$';
-> 0
mysql> SELECT 'pipi' REGEXP '^(pi)*$';
-> 1
{1}, {2,3}
{n}或{m,n}符號提供了編寫正則表達式的更通用方式,可以匹配模式的不少前述原子(或「部分」)。m和n均爲整數。
a*可被寫入爲a{0,}。
a+可被寫入爲a{1,}。
a?可被寫入爲a{0,1}。
更準確地講,a{n}與a的n個實例準確匹配。a{n,}匹配a的n個或更多實例。a{m,n}匹配a的m~n個實例,包含m和n。
m和n必須位於0~RE_DUP_MAX(默認爲255)的範圍內,包含0和RE_DUP_MAX。若是同時給定了m和n,m必須小於或等於n。
mysql> SELECT 'abcde' REGEXP 'a[bcd]{2}e';
-> 0
mysql> SELECT 'abcde' REGEXP 'a[bcd]{3}e';
-> 1
mysql> SELECT 'abcde' REGEXP 'a[bcd]{1,10}e';
-> 1
[a-dX], [^a-dX]
匹配任何是(或不是,若是使用^的話)a、b、c、d或X的字符。兩個其餘字符之間的「-」字符構成一個範圍,與從第1個字符開始到第2個字符之間的全部字符匹配。例如,[0-9]匹配任何十進制數字 。要想包含文字字符「]」,它必須緊跟在開括號「[」以後。要想包含文字字符「-」,它必須首先或最後寫入。對於[]對內未定義任何特殊含義的任何字符,僅與其自己匹配。
mysql> SELECT 'aXbc' REGEXP '[a-dXYZ]';
-> 1
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]$';
-> 0
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]+$';
-> 1
mysql> SELECT 'aXbc' REGEXP '^[^a-dXYZ]+$';
-> 0
mysql> SELECT 'gheis' REGEXP '^[^a-dXYZ]+$';
-> 1
mysql> SELECT 'gheisa' REGEXP '^[^a-dXYZ]+$';
-> 0
[.characters.]
在括號表達式中(使用[和]),匹配用於校對元素的字符序列。字符爲單個字符或諸如新行等字符名。在文件regexp/cname.h中,可找到字符名稱的完整列表。
mysql> SELECT '~' REGEXP '[[.~.]]';
-> 1
mysql> SELECT '~' REGEXP '[[.tilde.]]';
-> 1
[=character_class=]
在括號表達式中(使用[和]),[=character_class=]表示等同類。它與具備相同校對值的全部字符匹配,包括它自己,例如,若是o和(+)均是等同類的成員,那麼[[=o=]]、[[=(+)=]]和[o(+)]是同義詞。等同類不得用做範圍的端點。
[:character_class:]
在括號表達式中(使用[和]),[:character_class:]表示與術語類的全部字符匹配的字符類。標準的類名稱是:
alnum |
文字數字字符 |
alpha |
文字字符 |
blank |
空白字符 |
cntrl |
控制字符 |
digit |
數字字符 |
graph |
圖形字符 |
lower |
小寫文字字符 |
|
圖形或空格字符 |
punct |
標點字符 |
space |
空格、製表符、新行、和回車 |
upper |
大寫文字字符 |
xdigit |
十六進制數字字符 |
它們表明在ctype(3)手冊頁面中定義的字符類。特定地區可能會提供其餘類名。字符類不得用做範圍的端點。
mysql> SELECT 'justalnums' REGEXP '[[:alnum:]]+';
-> 1
mysql> SELECT '!!' REGEXP '[[:alnum:]]+';
-> 0
[[:<:]], [[:>:]]
這些標記表示word邊界。它們分別與word的開始和結束匹配。word是一系列字字符,其前面和後面均沒有字字符。字字符是alnum類中的字母數字字符或下劃線(_)。
mysql> SELECT 'a word a' REGEXP '[[:<:]]word[[:>:]]';
-> 1
mysql> SELECT 'a xword a' REGEXP '[[:<:]]word[[:>:]]';
-> 0
要想在正則表達式中使用特殊字符的文字實例,應在其前面加上2個反斜槓「\」字符。MySQL解析程序負責解釋其中一個,正則表達式庫負責解釋另外一個。例如,要想與包含特殊字符「+」的字符串「1+2」匹配,在下面的正則表達式中,只有最後一個是正確的:
mysql> SELECT '1+2' REGEXP '1+2';
-> 0
mysql> SELECT '1+2' REGEXP '1\+2';
-> 0
mysql> SELECT '1+2' REGEXP '1\\+2';
-> 1
如下是可用於隨REGEXP操做符的表的模式。
應用示例,查找用戶表中Email格式錯誤的用戶記錄:
1
2
3
|
SELECT
*
FROM
users
WHERE
email
NOT
REGEXP
'^[A-Z0-9._%-]+@[A-Z0-9.-]+.[A-Z]{2,4}$'
|
MySQL數據庫中正則表達式的語法,主要包括各類符號的含義。
(^)字符
匹配字符串的開始位置,如「^a」表示以字母a開頭的字符串。
1
2
3
4
5
6
7
8
|
mysql>
select
'xxxyyy'
regexp
'^xx'
;
+
-----------------------+
|
'xxxyyy'
regexp
'^xx'
|
+
-----------------------+
| 1 |
+
-----------------------+
1 row
in
set
(0.00 sec)
|
查詢xxxyyy字符串中是否以xx開頭,結果值爲1,表示值爲true,知足條件。
($)字符
匹配字符串的結束位置,如「X^」表示以字母X結尾的字符串。
(.)字符
這個字符就是英文下的點,它匹配任何一個字符,包括回車、換行等。
(*)字符
星號匹配0個或多個字符,在它以前必須有內容。如:
1
|
mysql>
select
'xxxyyy'
regexp
'x*'
;
|
這個SQL語句,正則匹配爲true。
(+)字符
加號匹配1個或多個字符,在它以前也必須有內容。加號跟星號的用法相似,只是星號容許出現0次,加號則必須至少出現一次。
(?)字符
問號匹配0次或1次。
實例:
如今根據上面的表,能夠裝置各類不一樣類型的SQL查詢以知足要求。在這裏列出一些理解。考慮咱們有一個表爲person_tbl和有一個字段名爲名稱:
查詢找到全部的名字以'st'開頭
1
|
mysql>
SELECT
name
FROM
person_tbl
WHERE
name
REGEXP
'^st'
;
|
查詢找到全部的名字以'ok'結尾
1
|
mysql>
SELECT
name
FROM
person_tbl
WHERE
name
REGEXP
'ok$'
;
|
查詢找到全部的名字包函'mar'的字符串
1
|
mysql>
SELECT
name
FROM
person_tbl
WHERE
name
REGEXP
'mar'
;
|
查詢找到全部名稱以元音開始和'ok'結束 的
1
|
mysql>
SELECT
name
FROM
person_tbl
WHERE
name
REGEXP
'^[aeiou]|ok$'
;
|
一個正則表達式中的可使用如下保留字
^
所匹配的字符串之後面的字符串開頭
1
2
|
mysql>
select
"fonfo"
REGEXP
"^fo$"
; -> 0(表示不匹配)
mysql>
select
"fofo"
REGEXP
"^fo"
; -> 1(表示匹配)
|
$
所匹配的字符串之前面的字符串結尾
1
2
3
|
mysql>
select
"fono"
REGEXP
"^fono$"
; -> 1(表示匹配)
mysql>
select
"fono"
REGEXP
"^fo$"
; -> 0(表示不匹配)
.
|
匹配任何字符(包括新行)
1
2
|
mysql>
select
"fofo"
REGEXP
"^f.*"
; -> 1(表示匹配)
mysql>
select
"fonfo"
REGEXP
"^f.*"
; -> 1(表示匹配)
|
a*
匹配任意多個a(包括空串)
1
2
3
|
mysql>
select
"Ban"
REGEXP
"^Ba*n"
; -> 1(表示匹配)
mysql>
select
"Baaan"
REGEXP
"^Ba*n"
; -> 1(表示匹配)
mysql>
select
"Bn"
REGEXP
"^Ba*n"
; -> 1(表示匹配)
|
a+
匹配任意多個a(不包括空串)
1
2
|
mysql>
select
"Ban"
REGEXP
"^Ba+n"
; -> 1(表示匹配)
mysql>
select
"Bn"
REGEXP
"^Ba+n"
; -> 0(表示不匹配)
|
a?
匹配一個或零個a
1
2
3
|
mysql>
select
"Bn"
REGEXP
"^Ba?n"
; -> 1(表示匹配)
mysql>
select
"Ban"
REGEXP
"^Ba?n"
; -> 1(表示匹配)
mysql>
select
"Baan"
REGEXP
"^Ba?n"
; -> 0(表示不匹配)
|
de|abc
匹配de或abc
1
2
3
4
5
6
|
mysql>
select
"pi"
REGEXP
"pi|apa"
; -> 1(表示匹配)
mysql>
select
"axe"
REGEXP
"pi|apa"
; -> 0(表示不匹配)
mysql>
select
"apa"
REGEXP
"pi|apa"
; -> 1(表示匹配)
mysql>
select
"apa"
REGEXP
"^(pi|apa)$"
; -> 1(表示匹配)
mysql>
select
"pi"
REGEXP
"^(pi|apa)$"
; -> 1(表示匹配)
mysql>
select
"pix"
REGEXP
"^(pi|apa)$"
; -> 0(表示不匹配)
|
(abc)*
匹配任意多個abc(包括空串)
1
2
3
|
mysql>
select
"pi"
REGEXP
"^(pi)*$"
; -> 1(表示匹配)
mysql>
select
"pip"
REGEXP
"^(pi)*$"
; -> 0(表示不匹配)
mysql>
select
"pipi"
REGEXP
"^(pi)*$"
; -> 1(表示匹配)
|
{1}
{2,3}
這是一個更全面的方法,它能夠實現前面好幾種保留字的功能
a*
能夠寫成a{0,}
a+
能夠寫成a{1,}
a?
能夠寫成a{0,1}
在{}內只有一個整型參數i,表示字符只能出現i次;在{}內有一個整型參數i,後面跟一個「,」,表示字符能夠出現i次或i次以上;在{}內只有一個整型參數i,後面跟一個「,」,再跟一個整型參數j,表示字符只能出現i次以上,j次如下(包括i次和j次)。其中的整型參數必須大於等於0,小於等於 RE_DUP_MAX(默認是255)。 若是有兩個參數,第二個必須大於等於第一個
[a-dX]
匹配「a」、「b」、「c」、「d」或「X」
[^a-dX]
匹配除「a」、「b」、「c」、「d」、「X」之外的任何字符。
「[」、「]」必須成對使用
1
2
3
4
5
6
|
mysql>
select
"aXbc"
REGEXP
"[a-dXYZ]"
; -> 1(表示匹配)
mysql>
select
"aXbc"
REGEXP
"^[a-dXYZ]$"
; -> 0(表示不匹配)
mysql>
select
"aXbc"
REGEXP
"^[a-dXYZ]+$"
; -> 1(表示匹配)
mysql>
select
"aXbc"
REGEXP
"^[^a-dXYZ]+$"
; -> 0(表示不匹配)
mysql>
select
"gheis"
REGEXP
"^[^a-dXYZ]+$"
; -> 1(表示匹配)
mysql>
select
"gheisa"
REGEXP
"^[^a-dXYZ]+$"
; -> 0(表示不匹配)
|