ORACLE 正規表示式

jinqibingl發表於2012-10-04

Oracle 正規表示式  

Oracle 正規表示式
正規表示式具有強大、便捷、高效的文字處理功能。能夠新增、刪除、分析、疊加、插
入和修整各種型別的文字和資料。Oracle 從 10g 開始支援正規表示式。
下面透過一些例子來說明使用正規表示式來處理一些工作中常見的問題。
1.  REGEXP_SUBSTR
REGEXP_SUBSTR 函式使用正規表示式來指定返回串的起點和終點,返回與 source_string 
字符集中的 VARCHAR2 或 CLOB 資料相同的字串。
語法:
--1.REGEXP_SUBSTR 與 SUBSTR 函式相同,返回擷取的子字串
REGEXP_SUBSTR(srcstr, pattern [, position [, occurrence [, match_option]]])
注:
   srcstr          源字串
   pattern         正規表示式樣式
   position        開始匹配字元位置
   occurrence      匹配出現次數
   match_option    匹配選項(區分大小寫)
 
1.1 從字串中擷取子字串
SELECT regexp_substr('1PSN/231_3253/ABc', '[[:alnum:]]+') FROM dual;
Output: 1PSN
[[:alnum:]]+ 表示匹配1個或者多個字母或數字字元。
 
SELECT regexp_substr('1PSN/231_3253/ABc', '[[:alnum:]]+', 1, 2) FROM dual;
Output: 231
與上面一個例子相比,多了兩個引數
1   表示從源字串的第一個字元開始查詢匹配
2   表示第2次匹配到的字串(預設值是“1”,如上例)
 
select regexp_substr() from dual;
Output: 231
@* 表示匹配0個或者多個@
[[:alnum:]]+ 表示匹配1個或者多個字母或數字字元
注意:需要區別“+”和“*”的區別
 
select regexp_substr() from dual;
Output: @
@+ 表示匹配1個或者多個@
[[:alnum:]]* 表示匹配0個或者多個字母或數字字元
 
select regexp_substr() from dual;
Output: Null
@+ 表示匹配1個或者多個@
[[:alnum:]]+ 表示匹配1個或者多個字母或數字字元
 
select regexp_substr() from dual;
Output: 125
[[:digit:]]+$ 表示匹配1個或者多個數字結尾的字元
 
select regexp_substr() from dual;
Output: /ABc
[^[:digit:]]+$ 表示匹配1個或者多個不是數字結尾的字元
 
select regexp_substr() from dual;
Output: Tom_Kyte
[^@]+ 表示匹配1個或者多個不是“@”的字元
 
select regexp_substr('1PSN/231_3253/ABc','[[:alnum:]]*',1,2) 
from dual;
Output: Null
[[:alnum:]]* 表示匹配0個或者多個字母或者數字字元
注:因為是匹配0個或者多個,所以這裡第2次匹配的是“/”(匹配了0次),而不是“231”,
所以結果是“Null”
1.2 匹配重複出現
查詢連續 2 個小寫字母
SELECT regexp_substr('Republicc Of Africaa', '([a-z])\1', 1, 1, 'i')
  FROM dual;
Output: cc
([a-z])   表示小寫字母a-z
\1         表示匹配前面的字元的連續次數
1          表示從源字串的第一個字元開始匹配
1          第一次出現符合匹配結果的字元
i          表示區分大小寫
查詢連續 3 個 6,7,8,9 中的數字
SELECT CASE
         WHEN regexp_like('Patch 10888 applied', '([6-9])\1\1') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: Match Found
1.3 其他一些匹配樣式
查詢網頁地址資訊
SELECT regexp_substr('Go to and click on database',
'http://([[:alnum:]]+\.?){3,4}/?') RESULT
  FROM dual
Output:
其中:
表示匹配字串“http://”
([[:alnum:]]+\.?) 表示匹配1次或者多次字母或數字字元,緊跟0次或1次逗號符
{3,4}               表示匹配前面的字元最少3次,最多4次
/?                  表示匹配一個反斜槓字元0次或者1次
提取 csv 字串中的第三個值
SELECT regexp_substr('1101,Yokohama,Japan,1.5.105', '[^,]+', 1, 3) AS output
  FROM dual;
Output: Japan
其中:
[^,]+    表示匹配1個或者多個不是逗號的字元
1         表示從源字串的第一個字元開始查詢匹配
3         表示第3次匹配到的字串
注:這個通常用來實現字串的列傳行
--字串的列傳行
SELECT regexp_substr('1101,Yokohama,Japan,1.5.105', '[^,]+', 1, LEVEL) AS output
  FROM dual
CONNECT BY LEVEL <= length('1101,Yokohama,Japan,1.5.105') -
           length(REPLACE('1101,Yokohama,Japan,1.5.105', ',')) + 1;
Output: 1101
        Yokohama
Japan
1.5.105
這裡透過 LEVEL 來迴圈擷取匹配到的字串。
下面這個例子,查詢源字串中是否包含 kid 、kids 或者 kidding 這三個字串
SELECT CASE
         WHEN regexp_like('Why does a kid enjoy kidding with kids only?',
                          'kid(s|ding)*',
                          'i') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: Match Found
其中:
kid          表示字串kid
(s|ding)*  表示匹配0次或者多次字元“s”或者“ding”
i            表示不區分大小寫
2.  REGEXP_INSTR
REGEXP_INSTR 函式使用正規表示式返回搜尋模式的起點和終點。REGEXP_INSTR
的語法如下所示。REGEXP_INSTR 返回一個整數,指出搜尋模式的開始或結束的位置,如
果沒有發現匹配的值,則返回 0。
語法:
--2.REGEXP_INSTR 與 INSTR 函式相同,返回字串位置
REGEXP_INSTR(srcstr, pattern [, position [, occurrence [, return_option [,match_option]]]])
與 REGEXP_SUBSTR 一樣,它也有變數 pattern、 position(開始位置 )、
occurrence 和 match_parameter;這裡主要介紹一下新引數 return_option 的作
用,它允許使用者告訴 Oracle,模式出現的時候,要返回什麼內容。
具體如下面的例子所示:
--如果 return_option 為 0 則,Oracle 返回第一個字元出現的位置。這是預設值,與 INSTR 的作用相同
SELECT regexp_instr('abc1def',
                    '[[:digit:]]') output
  FROM dual;
Output: 4
 
--如果 return_option 為 1,則 Oracle 返回跟在所搜尋字元出現以後下一個字元的位置。
--例如,下面的查詢返回了在串中發現的第一個數字的位置:
SELECT regexp_instr('abc1def',
                    '[[:digit:]]',1,1,1) output
  FROM dual;
Output: 5
3.  REGEXP_LIKE
除了上面列出的正規表示式函式,還可以使用 REGEXP_LIKE 函式。REGEXP_LIKE 支
持在 where 子句中使用正規表示式。
語法:
--3.REGEXP_LIKE 與 LIKE 函式相同,返回布林型別
REGEXP_LIKE(srcstr, pattern [,match_option])
3.1 驗證字串全部由字母組成
SELECT CASE
         WHEN regexp_like('Google', '^[[:alpha:]]{6}$') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: Match Found
在上面這個例子中,透過正規表示式來驗證字串是否由 6 個字母組成。解釋一下表
達式 ^[[:alpha:]]{6}$。
^              表示行的開始
[[:alpha:]]  表示字母
{6}            表示匹配的次數,這裡表示匹配6次
$              表示行的結尾
3.2 驗證字串全部由小寫字母組成
SELECT CASE
         WHEN regexp_like('Terminator', '^([[:lower:]]{3,12})$') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: Match Found
這裡如果我們把輸入字串改成“terminator”,則結果就是匹配了。上面的例子中,
透過正規表示式來驗證字串是否由 3 到 12 個小寫字母組成。其中:
{3,12}   表示匹配次數,最少3次,最多12次
3.3 區分大小寫
SELECT CASE
         WHEN regexp_like('Republic Of India', 'of', 'c') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: No Match Found
上面的例子中,透過正規表示式來驗證字串是否包含小寫的“of”。其中:
c    表示完全匹配,區分大小寫
如果改成下面這樣,則不區分大小寫:
SELECT CASE
         WHEN regexp_like('Republic Of India', 'of', 'i') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: Match Found
其中:
i    表示不區分大小寫
3.4 匹配第n 位置的字元
SELECT CASE
         WHEN regexp_like('ter*minator', '^...[^[:alnum:]]') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: Match Found
在上面的例子中,透過正規表示式來驗證字串“ter*minatory”的第 4 位的字元。
解釋一下表示式^...[^[:alnum:]],其中:
^              表示行的開始
.              表示匹配任意一個的字元(… 表示3個任意的字元)
[^[:alnum:]] 表示匹配不是字母和數字(^ 在方括號內,表示否定)
3.5 查詢控制字元
SELECT CASE
         WHEN regexp_like('Super' || chr(13) || 'Star', '[[:cntrl:]]') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: Match Found
上面的例子中,透過正規表示式來驗證字串中是否包含控制符。(13在ASCII碼中表示回
車符)
3.6 驗證SSN
SELECT CASE
         WHEN regexp_like('987-65-4321', '^[0-9]{3}-[0-9]{2}-[0-9]{4}$') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: Match Found
 
Input: 987-654-3210
Output: No match found
其中:
^          表示行的開始
[0-9]{3}  表示3個數字
-          表示連字號“-”
[0-9]{2}  表示2個數字
-          表示連字號“-”
[0-9]{4}  表示2個數字
$          表示行的結束
3.7 驗證email 地址
SELECT CASE
         WHEN regexp_like(,                      
'^([[:alnum:]]+(_?|\.))[[:alnum:]]*@[[:alnum:]]+(\.([[:alnum:]]+)){1,2}$') THEN
          'Match Found'
         ELSE
          'No Match Found'
       END AS output
  FROM dual;
Output: Match Found
將上面的正規表示式透過字元“@”分為兩部分:
前半部分 ^([[:alnum:]]+(_?|\.))[[:alnum:]]* ,其中:
^       表示行的開始
([[:alnum:]]+(_?|\.)) 表示匹配以1個或多個字元或者數字字元,緊跟著字元“
或者字元“.”
_”
[[:alnum:]]* 表示匹配0個或者多個字母或者數字字元
後半部分 [[:alnum:]]+(\.([[:alnum:]]+)){1,2}$,其中:
[[:alnum:]]+ 表示匹配1個或者多個字母或者數字字元
(\.([[:alnum:]]+)){1,2} 表示匹配1個或者2個,“.”加上1個或者多個字母或
者數字字元(例如:.com.cn 或者 .co.in)
$       表示行的結尾
 
輸入:
輸出:Match Found
 
輸入:
輸出:No Match Found
 
注:上面出現的“\.”中“\”表示轉義符,因為“”是關鍵字元,匹配任意字元,所以需要轉
義符。
 
4.  REGEXP_REPLACE
REGEXP_REPLACE 函式是用另外一個值來替代串中的某個值。例如,可以用一個匹配
數字來替代字母的每一次出現。REGEXP_REPLACE 的格式如下所示
語法:
--4.REGEXP_REPLACE 與 REPLACE 函式相同,替換原字串中的字元內容
REGEXP_REPLACE(srcstr, pattern [,replacestr [, position [, occurrence [,match_option]]]])
4.1 查詢替換空格符
SELECT regexp_replace('Help Earth Stay Green', '[[:blank:]]{2,8}', ' ')
  FROM dual;
Output: Help Earth Stay Green
上面的例子中,用正規表示式將字串中多個空格替換為一個空格。其中:
[[:blank:]]{2,8}  表示2到8個空格
注:這裡有目的的沒有包含(^$) 元字元,是因為需要匹配字串中的任何位置,所以不需
要這兩個位置匹配符。^[[:blank:]]{2,8}$ 這樣表示字串中只包含2-8個空格
4.2 格式化字串
SELECT regexp_replace('04099661234',                     
'([[:digit:]]{3})([[:digit:]]{4})([[:digit:]]{4})',
                      '(\1) \2-\3') AS formatted_phone
  FROM dual;
Output: (040) 9966-1234
([[:digit:]]{3}) 表示3個數字   ---?  \1
([[:digit:]]{4}) 表示4個數字   ---?  \2
([[:digit:]]{4}) 表示4個數字   ---?  \3
所以 “(\1) \2-\3” 表示將前3個數字用圓括號,緊跟著一個空格,再跟著中間4個資料,
再跟著連字元“-”,最後是後4位的數字。
 
更多格式化字串的例子
SELECT regexp_replace('04099661234',                     
'^([[:digit:]]{1})([[:digit:]]{2})([[:digit:]]{4})([[:digit:]]{4})$',
                      '+91-\2-\3-\4') AS formatted_phone
  FROM dual;
Output: +91-40-9966-1234
下面一個例子中,在每兩個字元之間插入一個空格符
SELECT regexp_replace('YAHOO', '(.)', '\1 ') AS output FROM dual;
Output: Y A H O O
5.  附註:
5.1 元字元
*    匹配0次或者多次出現
+    匹配1次或者多次出現
?   匹配0次或者1次出現
^    匹配行的開始字元
$    匹配行的結束字元
.    匹配任意一個字元(除了NULL)
\    反斜線字元根據上下文有4種不同的含義。它可以表示本身、引用下一個字元、引入一個
運算子或者什麼都不做
[]   方括號表示指定一個匹配列表,該列表匹配列表中顯示的任何表示式。
[^]  同上面相反,非匹配列表表示式
()   分組表示式,看作單個子表示式
{m}  匹配m次
{m,} 至少匹配m次
{m,n} 至少匹配m次,但是不能超過n次
[::]  指定字元類。例如,[:alpha:]。可以匹配字元類中的任何字元
[==]  指定等價類。例如,[=a=]匹配所有包含基本字母“a”的字元
5.2 匹配選項
i  用於不區分大小寫的匹配
c  用於區分大小寫的匹配
n  允許句點(.)作為萬用字元(請參閱表 8-1)去匹配換行符。如果省略該引數,則句點將不匹配換行符
m  將源字串視為多行。即 Oracle 將“^”和“$”分別看作源字串中任意位置任何行的開始和結束,而
不是僅僅看作整個源字串的開始或結束。如果省略該引數,則 Oracle 將源字串看作一行
 
5.3 字元類
[:alnum:] 所有的字母和數字字元  
[:alpha:] 所有的字母字元  
[:blank:] 所有的空格字元  
[:cntrl:] 所有的控制字元(不會列印出來)  
[:digit:] 所有的數字  
[:graph:] 所有的[:punct:]、[:upper:]、[:lower:]和[:digit:]字元  
[:lower:] 所有的小寫字母  
[:print:] 所有可列印的字元  
[:punct:] 所有的標點符號  
[:space:] 所有的空隔字元(不會列印出來)  
[:upper:] 所有的大寫字母  
[:xdigit:] 所有有效的十六進位制字元 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9606200/viewspace-745687/,如需轉載,請註明出處,否則將追究法律責任。

相關文章