模式 | 描述 |
---|---|
^ | 匹配輸入字符串的開始位置。如果設置了 RegExp 對象的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之后的位置。 |
$ | 匹配輸入字符串的結束位置。如果設置了RegExp 對象的 Multiline 屬性,$ 也匹配 '\n' 或 '\r' 之前的位置。 |
. | 匹配除 "\n" 之外的任何單個字符。要匹配包括 '\n' 在內(nèi)的任何字符,請使用象 '[.\n]' 的模式。 |
[...] | 字符集合。匹配所包含的任意一個字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 |
[^...] | 負值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。 |
p1|p2|p3 | 匹配 p1 或 p2 或 p3。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 則匹配 "zood" 或 "food"。 |
* | 匹配前面的子表達式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價于{0,}。 |
+ | 匹配前面的子表達式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價于 {1,}。 |
{n} | n 是一個非負整數(shù)。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個 o。 |
{n,m} | m 和 n 均為非負整數(shù),其中n = m。最少匹配 n 次且最多匹配 m 次。 |
實例
了解以上的正則需求后,我們就可以根據(jù)自己的需求來編寫帶有正則表達式的SQL語句。以下我們將列出幾個小實例(表名:person_tbl )來加深我們的理解:
查找name字段中以'st'為開頭的所有數(shù)據(jù):
mysql> SELECT name FROM person_tbl WHERE name REGEXP '^st';
查找name字段中以'ok'為結尾的所有數(shù)據(jù):
mysql> SELECT name FROM person_tbl WHERE name REGEXP 'ok$';
查找name字段中包含'mar'字符串的所有數(shù)據(jù):
mysql> SELECT name FROM person_tbl WHERE name REGEXP 'mar';
查找name字段中以元音字符開頭或以'ok'字符串結尾的所有數(shù)據(jù):
mysql> SELECT name FROM person_tbl WHERE name REGEXP '^[aeiou]|ok$';
mysql正則REGEXP學習練習筆記
REGEXP在mysql是用來執(zhí)行正則表達式的一個函數(shù),像php中的preg之類的函數(shù)了,regexp正則函數(shù)如果只是簡單的查詢使用like即可,但復雜的還是需要使用regexp了,下面我們來看看。
MySql用戶手冊建議,在構造簡單查詢時,仍使用通配符。
如:
Select [*|fieldname list] From [tablename] where [fieldname] like ["%someletter"|"%someletter%","_","?someletter"];
但在一些特殊查詢中,不用正則表達式是不行的。MYSQL提供的正則表達式WHERE謂詞有三個,分別是:
REGEXP, RLIKE, NOT RLIKE
用這三個替換原有的LIKE謂詞,后面即可以跟正則表達式。
例如要查詢字段中含有“_”的數(shù)據(jù),則要用以下查詢語句:
SELECT * FROM TABLENAME WHERE FIELDNAME RLIKE '.[_].';
擴展正則表達式的一些字符是:
· ‘.'匹配任何單個的字符。
· 字符類“[...]”匹配在方括號內(nèi)的任何字符。例如,“[abc]”匹配“a”、“b”或“c”。為了命名字符的范圍,使用一個“-”?!癧a-z]”匹配任何字母,而“[0-9]”匹配任何數(shù)字。
· “ * ”匹配零個或多個在它前面的字符。例如,“x*”匹配任何數(shù)量的“x”字符,“[0-9]*”匹配任何數(shù)量的數(shù)字,而“.*”匹配任何數(shù)量的任何字符。
如果REGEXP模式與被測試值的任何地方匹配,模式就匹配(這不同于LIKE模式匹配,只有與整個值匹配,模式才匹配)。
為了定位一個模式以便它必須匹配被測試值的開始或結尾,在模式開始處使用“^”或在模式的結尾用“$”。
為了找出以“b”開頭的名字,使用“^”匹配名字的開始:
使用正則
SELECT * FROM pet WHERE name REGEXP BINARY ‘^b';
SELECT * FROM pet WHERE name REGEXP ‘fy$';
SELECT * FROM pet WHERE name REGEXP ‘w';
SELECT * FROM pet WHERE name REGEXP ‘^…..$';
SELECT * FROM pet WHERE name REGEXP ‘^.{5}$';
今天在應用中遇到了這樣的一個問題,
有一個字段 t1,其中的值類似于:1,1,1,2,3,3,4,4,5,5,2,4,3,2,1,2
需要從里面搜索出比如說:第一個逗號前的數(shù)字范圍為3-5之間,第三個逗號前的數(shù)字的范圍為3-5之間,第10個逗號前的數(shù)字范圍為3-5之間,其余的都為1-5之間。。。
則sql語句可以這么寫:
SELECT * FROM tb WHERE t1 REGEXP '^[3-5],[1-5],[3-5],[1-5],[1-5],[1-5],[1-5],[1-5],[1-5],[3-5],[1-5],[1-5],[1-5],[1-5],[1-5],[1-5]%';
1. 使用LIKE和NOT LIKE比較操作符(注意不能使用=或!=);
2. 模式默認是忽略大小寫的;
3. 允許使用”_”匹配任何單個字符,”%”匹配任意數(shù)目字符(包括零字符);
附一些mysql正則規(guī)則
^ 匹配字符串的開始部分
$ 匹配字符串的結束部分
. 匹配任何字符(包括回車和新行)
a* 匹配0或多個a字符的任何序列
a+ 匹配1個或多個a字符的任何序列
a? 匹配0個或1個a字符
de|abc 匹配序列de或abc
(abc)* 匹配序列adc的0個或者多個實例
{n}、{m,n} {n}或{m,n}符號提供了編寫正則表達式的更通用方式,能夠匹配模式的很多前述原子(或“部分”)。m和n均為整數(shù)。
a* 可被寫為a{0,}
a+ 可被寫為a{1,}
a? 可被寫為a{0,1}
[a-dX] 匹配任何是a,b,c,d或者X的字符,兩個其他字符之間的'-'字符構成一個范圍
[^a-dX] 匹配任何不是a,b,c,d或者X的字符,前面的字符'^'是否定的意思
[.characters.] 在括號表達式中(使用[和]),匹配用于校對元素的字符序列,字符為單個字符或新行等字符名
mysql> SELECT ‘~' REGEXP ‘[[.~.]]'; -> 1
mysql> SELECT ‘~' REGEXP ‘[[.tilde.]]'; -> 1
[=character_class=]
在括號表達式中(使用[和]),[=character_class=]表示等同類。它與具有相同校對值的所有字符匹配,包括它本身,
[[=a=]] 等同于[a(+)],[a+],[a{1,}]
[:character_class:]
在括號表達式中(使用[和]),[:character_class:]表示與術語類的所有字符匹配的字符類。
標準的類名稱是:
alnum 文字數(shù)字字符
alpha 文字字符
blank 空白字符
cntrl 控制字符
digit 數(shù)字字符
graph 圖形字符
lower 小寫文字字符
print 圖形或空格字符
punct 標點字符
space 空格、制表符、新行、和回車
upper 大寫文字字符
xdigit 十六進制數(shù)字字符
[[::]], [[:>:]]
這些標記表示word邊界。它們分別與word的開始和結束匹配。word是一系列字字符,其前面和后面均沒有字字符。字符是alnum類中的字母數(shù)字字符或下劃線(_)。
mysql> select ‘fang shan zi' regexp ‘[[::]]shan[[:>:]]'; -> 1
mysql> select ‘fang shan zi' regexp ‘[[::]]fang[[:>:]]'; -> 1
mysql> select ‘fang shans zi' regexp ‘[[::]]shan[[:>:]]'; -> 0
正則表達式使用特殊字符,應在其前面加上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
MySQL 查尋條件使用正則 regexp
我用的是 Mybatis
t.hobby : 條件字段
hobby : 查尋參數(shù),值可以是多個逗號分隔的值:‘閱讀,交友,圍棋'
!-- t.hobby 的值最初可能是這樣: ' 吃, 喝,嫖,賭 , 抽,坑,蒙,拐,騙,偷 ' 每個詞的兩邊有空格不規(guī)則 -->
!-- 下面逐步演示 -->
if test="hobby!=null and hobby!=''">
concat(',',REPLACE (t.hobby, ' ', ''),',') regexp concat(',(',replace(#{hobby},',','|'),'),')
/if>
!-- 表字段 t.hobby 取出值 -->
if test="hobby!=null and hobby!=''">
concat(',',REPLACE (' 吃, 喝,嫖,賭 , 抽,坑,蒙,拐,騙,偷 ', ' ', ''),',') regexp concat(',(',replace(#{hobby},',','|'),'),')
/if>
!-- 表字段值處理后,去掉了多余的空格 -->
if test="hobby!=null and hobby!=''">
concat(',','吃,喝,嫖,賭,抽,坑,蒙,拐,騙,偷',',') regexp concat(',(',replace(#{hobby},',','|'),'),')
/if>
!-- concat后得到一個字符串,首尾加上了逗號 -->
if test="hobby!=null and hobby!=''">
',吃,喝,嫖,賭,抽,坑,蒙,拐,騙,偷,' regexp concat(',(',replace(#{hobby},',','|'),'),')
/if>
!-- 取出參數(shù) #{hobby} 的值 -->
if test="hobby!=null and hobby!=''">
',吃,喝,嫖,賭,抽,坑,蒙,拐,騙,偷,' regexp concat(',(',replace('吃,喝,嫖,嫖',',','|'),'),')
/if>
!-- 把逗號換成 | -->
if test="hobby!=null and hobby!=''">
',吃,喝,嫖,賭,抽,坑,蒙,拐,騙,偷,' regexp concat(',(','吃|喝|嫖|嫖','),')
/if>
!-- concat后得到一個字符串,首尾加上了括號,逗號 -->
if test="hobby!=null and hobby!=''">
',吃,喝,嫖,賭,抽,坑,蒙,拐,騙,偷,' regexp ',(吃|喝|嫖|嫖),' !-- 紀念于謙老師不賭的美德 -->
/if>
得到結果是 1 作為條件就是真了。
復雜的過程主要是用來處理查尋條件。得到符合要求的正則作條件就ok了
但個人覺得,更理想的方式是:
被查尋字段在當初存入數(shù)據(jù)時就處理好格式:'吃,喝,嫖,賭,抽,坑,蒙,拐,騙,偷'
查尋條件可以處理好傳進來:',(吃|喝|嫖|嫖),'
那么一個查尋就可以簡化成這樣
if test="hobby!=null and hobby!=''">
concat(',', t.hobby ,',') regexp #{hobby}
/if>
到這就差不多了,基本上就可以看得懂了,實在不行就參考下面的相關文章。