oracle正則表達式的使用

原文鏈接:http://blog.sina.com.cn/s/blog_69e7b8d701012tuj.html

 

oracle數據庫當中有字符處理的函數,比如substr()replace()instr(),當然也有做字符匹配的操作符like,不過這些函數和操作符在處理一些複雜的字符串時,會顯得有些力不從心。從oracle 10g開始,Oracle內建了符合IEEE POSIX (Portable Operating System for Unix)標準的正則表達式。當然oracle也支持perl的正則表達式規則。熟練使用正則表達式,可以寫出簡潔,強大的SQL語句。實際上,它們類似於已有的操作符,但現在增加了強大的模式匹配功能。被搜索的數據可以是簡單的字符串或是存儲在數據庫字符列中的大量文本。正規表達式讓您能夠以一種您以前從未想過的方式來搜索、替換和驗證數據,並提供高度的靈活性。同時,正則表達式對oracle的約束也給與了加強。

正規表達式  

正規表達式由一個或多個字符型文字或元字符組成。在最簡單的格式下,正規表達式僅由字符文字組成,如正規表達式 cat。它被讀作字母 c,接着是字母 a  t,這種模式匹配 catlocation catalog 之類的字符串。元字符提供算法來確定 Oracle 如何處理組成一個正規表達式的字符。當您瞭解了各種元字符的含義時,您將體會到正規表達式用於查找和替換特定的文本數據是非常強大的。如果我們簡單理解的話,正則表達式就是一種字符串的組成和表示方法。

在使用這個新功能之前,您需要了解一些元字符的含義。句號 (.) 匹配一個正規表達式中的任意字符(除了換行符)。例如,正規表達式 a.b 匹配的字符串中首先包含字母 a,接着是其它任意單個字符(除了換行符),再接着是字母 b。字符串 axbxaybx  abba 都與之匹配,因爲在字符串中隱藏了這種模式。如果您想要精確地匹配以 a 開頭和以 b 結尾的一條三個字母的字符串,則您必須對正規表達式進行定位。脫字符號 (^) 元字符指示一行的開始,而美元符號 ($) 指示一行的結尾。因此, 正規表達式 ^a.b$ 匹配字符串 aababb  axb。將這種方式與 LIKE 操作符提供的類似的模式匹配 a_b 相比較,其中 "_" 是單字符通配符。

下表是正則表達式部分元字符的解釋(符合POSIX標準):

^           

使表達式定位至一行的開頭 

$

使表達式定位至一行的末尾

*

匹配 0 次或更多次

?

匹配 0 次或 1 

+

匹配 1 次或更多次

{}

正好匹配 m 

{m,}

至少匹配 m 

{m,n}

至少匹配 m 次但不超過 n 

[:alpha:]

字母字符

[:lower:]

小寫字母字符

[:upper:]

大寫字母字符

[:digit:]

數字

[:alnum:]

字母數字字符

[:space:]

空白字符(禁止打印),如回車符、換行符、豎直製表符和換頁符

[:punct:]

標點字符

...

將子表達式分組爲一個替換單元、量詞單元或後向引用單元  

[...]      

匹配列表中的字符

[^...]

匹配不在列表中的字符

Oracle提供了四個支持正則表達式的函數:

REGEXP_LIKE , REGEXP_REPLACE , REGEXP_INSTR , REGEXP_SUBSTR 

REGEXP_LIKE:比較一個字符串是否與正則表達式匹配  

(srcstr, pattern [, match_option])  

REGEXP_INSTR:在字符串中查找正則表達式,並且返回匹配的位置 

(srcstr, pattern [, position [, occurrence [, return_option [, match_option]]]])  

REGEXP_SUBSTR:返回與正則表達式匹配的子字符串  

(srcstr, pattern [, position [, occurrence [, match_option]]])    

REGEXP_REPLACE:搜索並且替換匹配的正則表達式  

(srcstr, pattern [, replacestr [, position [, occurrence [, match_option]]]])

其中各參數的含義爲:

srcstr:        被查找的字符數據,可以是列和綁定變量等   

pattern:       正則表達式。  

occurrence:    出現的次數。默認爲1  

position:      開始位置  

return_option: 默認值爲0,返回該模式的起始位置;值爲1則返回符合匹配條件的下一個字符的起始位置。  

replacestr:    用來替換匹配模式的字符串。  

match_option:  匹配方式選項。缺省爲c  

               ccase sensitive  

               Icase insensitive 

               n(.)匹配任何字符(包括newline)  

               m:字符串存在換行的時候被作爲多行處理

下面通過一些具體的例子來說明如何使用這四個函數。在測試當中,你就會逐步的體會到這些正則表達式的優勢

首先創建測試表TEST,並加載測試數據:
scott@DB01> create table test (c1 int , testcol varchar2(100));
Table created.
scott@DB01> insert into test values(100,'10d6h2');
1 row created.
scott@DB01> insert into test values(110,'100025');
1 row created.
scott@DB01> insert into test values(120,'gift');
1 row created.
scott@DB01> insert into test values(130,'01083697902');
1 row created.
scott@DB01> insert into test values(140,'010-400-7591');
1 row created.
scott@DB01> insert into test values(150,'ab c de');
1 row created.
scott@DB01> insert into test values(160,'abcde');
1 row created.
scott@DB01> insert into test values(170,'[email protected]'|| chr(10) ||'[email protected]');
1 row created.
scott@DB01> insert into test values(180,'Steven');
1 row created.
scott@DB01> insert into test values(190,'bac');
1 row created.
scott@DB01> insert into test values(200,'Stephen');
1 row created.
scott@DB01> commit;
Commit complete.

scott@DB01> col testcol for a60
scott@DB01> select * from test;
        C1 TESTCOL
------------------------------------------------------------
       100 10d6h2
       110 100025
       120 gift
       130 01083697902
       140 010-400-7591
       150 ab c de
       160 abcde
       170 [email protected]
         [email protected]
       180 Steven
       190 bac
       200 Stephen
11 rows selected.

一、REGEXP_LIKE測試
1.找到表中testcol列只包含數字的記錄
scott@DB01> select * from test where regexp_like(testcol,'^[0-9]+$');
        C1 TESTCOL
---------- ------------------------------------------------------------
       110 100025
       130 01083697902

2.找到表中testcol列只包含6個數字的記錄
scott@DB01> select * from test where regexp_like(testcol,'^[0-9]{6}$');
        C1 TESTCOL
---------- ------------------------------------------------------------
       110 100025

3.當然上面2的語句也可以使用下面的寫法
scott@DB01> select * from test where regexp_like(testcol,'^\d{6}$');
        C1 TESTCOL
---------- ------------------------------------------------------------
       110 100025
      
4.
找到表中testcol列包含以Ste開頭,中間是v或者是ph,以en結尾的字符串記錄
scott@DB01> select * from test where regexp_like(testcol,'^Ste(v|ph)en$');

        C1 TESTCOL
---------- ------------------------------------------------------------
       180 Steven
       200 Stephen

5.上面的語句默認是區分大小寫的,如果要不區分大小寫的話,可以考慮使用'i'
scott@DB01> select * from test where regexp_like(testcol,'^ste(v|ph)en$');
no rows selected

scott@DB01> select * from test where regexp_like(testcol,'^ste(v|ph)en$','i');
        C1 TESTCOL
---------- ------------------------------------------------------------
       180 Steven
       200 Stephen

6.找到表中testcol列只包含字母字符的記錄             
scott@DB01> select * from test where regexp_like(testcol,'^[[:alpha:]]+$');
        C1 TESTCOL
---------- ------------------------------------------------------------
       120 gift
       160 abcde
       180 Steven
       190 bac
       200 Stephen

7.如果想要找到表test中的testcol列以liu開頭,中間字符任意,組後以cn結束,直接寫語句是不行的,需要用到'm',視記錄爲多行 
scott@DB01> select * from test where regexp_like(testcol,'^liu.*cn$');
no rows selected

scott@DB01> select * from test where regexp_like(testcol,'^liu.*cn$','m');
        C1 TESTCOL
---------- ------------------------------------------------------------
       170 [email protected]
           [email protected]

二、REGEXP_INSTR測試
1.返回表中testcol列第一個非數字字符出現的位置
scott@DB01> col testcol for a30
scott@DB01> set linesize 140
scott@DB01> select c1,testcol,regexp_instr(testcol,'\D') from test;

        C1 TESTCOL                       REGEXP_INSTR(TESTCOL,'\D')
---------- ------------------------------ --------------------------
       100 10d6h2                                                  3
       110 100025                                                  0
       120 gift                                                    1
       130 01083697902                                             0
   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章