巷尾的酒吧

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            64 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

          需求:

          匹配手機號,第一位可以是+,可以沒有+,后面的全部要是數字,如:

          +861359415665

          8613659558555

          1356856455

          都是合法的。

          +aa156945555

          aa1359556666

          aaddssdfdfsd

          都是不合法的。

          正則:

          [sql]
          1. SQL> SELECT * FROM DUAL WHERE regexp_like('+333333' ,'^[\+]*[[:digit:]]+');      --該+轉義或者不轉義,結果是一樣的   
          2.   
          3. DUMMY  
          4. -----   
          5. X  

          [sql]

          1. SQL> SELECT * FROM DUAL WHERE regexp_like('aa333333' ,'^[+]*[[:digit:]]+');  
          2.   
          3. DUMMY  
          4. -----  

          解釋:

          1.^代表開始,*表示出現0次或多次,+表示出現1次或多次,[:digit:]代表0-9的純數字(還有$代表以什么結尾,如果是[[:digit:]]+$代表以數字結尾)。該正則的意思就是:

          以+0次或多次開頭,緊接著后面數字出現一次或多次(即一定要有數字)。

          2.dual表中,永遠只有1行記錄。查詢出dual中有記錄,證明where條件成立,反之不成立。

          先前寫了一個錯誤的正則:

          [sql]
          1. [\+]*[[:digit:]]+  

          注意,就只少了一個代表開始符號的^。少了這個符號,說明這個正則的意思是:

          +出現0次或多次(即+可以出現,可以不出現!!),緊后面的數字出現1次或多次。前面已經+可以出現0次了,證明沒有+也可以,那么就是只要字符串中有數字(+aa111a,aass11111……),這個正則恒成立,錯誤深重?。?!

          Oracle正則表達式的應用by 溫州--名次

          在oracle里正則表達式有四個函數可用,分別是regexp_like、regexp_substr、regexp_instr 和regexp_replace。這里在我們oracle 10g里靈活應用。

                 先來簡單介紹一下正則表達式的內容,正則表達式是做為快速查詢的文本內容的,在linux應用比較多,首先,行的起始與結束 “^”這個字符是表示只查找行首的內容。“$”這個字符只查找行末的內容。接下來是“^”還可以做為一個排除字符來使用。還是使用例子來做一個演示比較明了一下。

                 這里我使用regexp_like這個函數來做,這樣可以我們平時會使用的比較多。

          select * from test_table

          where regexp_like(field_1,'^1234')

          這個就是表示是以1234打頭的字符串是不是有匹配的。這里和like的方式是一樣的。

           

           

          select * from test_table

          where regexp_like(field_1,'^[12]234')

          這里多了一個[]這里做一個獨立字符,這里表示是以1或2開始,并且接著是234這個里的字符就會是匹配的。

           

           

          select * from test_table

          where regexp_like(field_1,'^(歐陽|李)小二')

          這里我們就可以表達,這個查詢一個姓是歐陽或李的,名字叫小二的字符串。這里多了一個()這個是做一個為字符串的方式來寫的與[]剛好是對應。

          這里還有一個“|”來表示或的意思。

           

           

          select * from test_table

          where regexp_like(field_1,'^李[小]*二')

          這里我們就可以查詢李小二或是李二,再或者是李小小二,都可以,這里我們需要講一下是[]后面帶了一個*,這個是表示0~無窮大 字符去匹配。這個[]我們還可以添加一個“+”來表示1~無窮大的字符去匹配,也可以更加精準一些,在[]后面{1,3}這里就是表示1個到3個相同字符的匹配。還有一個“?”來說表示1或是0個。

           

           

          select * from test_table

          where regexp_like(field_1,'李[^小]二')

          這里我們可以查詢到姓李的,但是第二字不是“小”這個字。

           

           

          select * from test_table

          where regexp_like(field_1,'[0-9]')

          這里是表示我們查詢字符串含有0-9的數字的字符串。

           

           

          select * from test_table

          where regexp_like(field_1,'[a-z]')

          這里是表示我們查詢字符串含有a-z的小寫字母的字符串。

           

           

          select * from test_table

          where regexp_like(field_1,'[A-z]')

          這里是表示我們查詢字符串含有A-z的所有字母的字符串。

           

           

          select * from test_table

          where regexp_like(name,'[[:alpha:]]')

          這里是表示查詢匹配任意字母,也包括中文字

           

           

          select * from test_table

          where regexp_like(name,'[[:alnum:]]')

          這里是表示查詢匹配任意字母和數字

           

           

          select * from test_table

          where regexp_like(name,'[[:digit:]]')

          這里是表示查詢匹配任意數字

           

           

          Select * from test_table

          Where regexp_like(name,’of’,’i’)

          這里就是of不區分大小寫

           

           

          Select * from test_table

          Where regexp_like(name,’^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$’)

          這樣我們可以查詢是不是ip格式

           

           

           

          接下來介紹一下regexp_substr

          這個也是一個非常實用的一個函數

           

           REGEXP_SUBSTR與SUBSTR函數相同,返回截取的子字符串

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

          注:

          srcstr 源字符串

          pattern 正則表達式樣式

          position 開始匹配字符位置

          occurrence 匹配出現次數

          match_option 匹配選項(區分大小寫)

           

           

          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('@@/231_3253/ABc','@*[[:alnum:]]+') from dual;

          Output: 231

          @* 表示匹配0個或者多個@

          [[:alnum:]]+ 表示匹配1個或者多個字母或數字字符

          注意:需要區別“+”和“*”的區別

           

           

          select regexp_substr('1@/231_3253/ABc','@+[[:alnum:]]*') from dual;

          Output: @

          @+ 表示匹配1個或者多個@

          [[:alnum:]]* 表示匹配0個或者多個字母或數字字符

           

           

          select regexp_substr('1@/231_3253/ABc','@+[[:alnum:]]+') from dual;

          Output: Null

          @+ 表示匹配1個或者多個@

          [[:alnum:]]+ 表示匹配1個或者多個字母或數字字符

           

           

          select regexp_substr('@1PSN/231_3253/ABc125','[[:digit:]]+$') from dual;

          Output: 125

          [[:digit:]]+$ 表示匹配1個或者多個數字結尾的字符

           

           

          select regexp_substr('1@/231_3253/ABc','@+[[:alnum:]]+') from dual;

          Output: Null

          @+ 表示匹配1個或者多個@

          [[:alnum:]]+ 表示匹配1個或者多個字母或數字字符

           

           

          select regexp_substr('@1PSN/231_3253/ABc125','[[:digit:]]+$') from dual;

          Output: 125

          [[:digit:]]+$ 表示匹配1個或者多個數字結尾的字符

           

           

          select regexp_substr('@1PSN/231_3253/ABc','[^[:digit:]]+$') from dual;

          Output: /ABc

          [^[:digit:]]+$ 表示匹配1個或者多個不是數字結尾的字符

           

           

          select regexp_substr('Tom_Kyte@oracle.com','[^@]+') 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”

           

           

          這里我們有時候會查詢字符串里asdfafd<main>dafda 這里我們要取出<main>這個字符串

          Select regexp_substr('asdfafd<main>dafda','<[^>]+>') from dual

          Output: <main>

          這里我們在<>中間去一個^>這樣在匹配<之后,在向后查詢的時候確保在匹配到>之前不再在有>,不然的話就要有可以出錯的情況。

           

           

          Select regexp_substr('asdfafd<main>da>fda','<[^<]+>') from dual

          Output: <main>da>

          在這個例子中,我們在<main>之后還在da>,這樣的話,如果我們沒有添加^>,正則表達式就會向后繼續去匹配,直到最后一個>為至,這樣就會出現偏差

           

           

          這個通常用來實現字符串的列傳行

          select regexp_substr('123;234;345;456;567;678;789','[^;]+',1,rownum) from dual

          connect by rownum <= length('123;234;345;456;567;678;789') - length(replace('123;234;345;456;567;678;789',';'))+1

          這里length這里操作是先得到有多少個“;”,再通過 connect by rownum方式來做一行成多行的操作,在變成多行之后,可以通過regexp_substr來取字符串的操作

           

           

          接著上一個例子

          a,b,c,d,e,d,f,a,n這樣的一個字符串,我們現在要把字符串里一些重復去掉,這樣的話結果是a,b,c,d,e,f,n去掉了d與a的兩個字符串

          select wm_concat(new_row) from (

          select distinct regexp_substr('a,b,c,d,e,d,f,a,n','[^,]+',1,rownum) new_row from dual

          connect by rownum<=length('a,b,c,d,e,d,f,a,n')-length(replace('a,b,c,d,e,d,f,a,n',',')))

          通過轉成多行的,再用distinct 去掉重復,然后我們再通過wm_concat來字符串合并來完成。

           

           

          再來一個ip格式轉換的例子吧,我們一般的IP的格式是12.19.168.27現在要不足3位的補足前面為0,結果是012.019.168.027

          select wm_concat(new_value) from (

          select

          lpad(regexp_substr('12.19.168.27','[^.]+',1,rownum) ,3,'0') new_value,rownum

          from dual

          connect by rownum<5

          order by rownum)

           

           

          來一個驗證IP是數字是否正確

          select count(*) from(

          select

          lpad(regexp_substr('12.19.168.27','[^.]+',1,rownum) ,3,'0') new_value,rownum

          from dual

          connect by rownum<5)

          where new_value>=0 and new_value<256

          having count(*) =4

           

           

          來一個IP字符串格式轉換成數字型IP

          select sum(new_value*power(256,4-rm)) from (

          select regexp_substr('12.19.168.27','[^.]+',1,rownum) new_value,rownum rm from dual

          connect by rownum<=4

          )

           

           

          接下來介紹一個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,模式出現的時候,要返回什么內容。

           

          Select regexp_instr('asdfafd<main>da>fda','sd') from dual

          Output:2

          這里去查詢sd的位置,這個和instr是在相同的

           

           

          Select regexp_instr('asdfafd<main>da>fda','da',1,2) from dual

          這里是查詢da第二出現的位置

           

          還有我們經常會遇到一種情況是,查詢某個字段,如果是等于“上海”或“北京”或者我們溫州就寫成大城市,其它的寫成小城市,我們一般會考慮使用decode這種方式

           

          Select decode('上海','上海','大城市','北京' ,'大城市' ,'溫州' ,'大城市','小城市') from dual

          只有兩個我們可能覺的sql也不是很冗長,如果有四五個的話,就有點長了,這里使用regexp_instr就可以很多的去操作

           

          Select decode (regexp_instr('北京','^(上海|北京|溫州)'),0,'小城市', '大城市') from dual

          通過regexp_instr不匹配時為0的條件,這樣就可以完成了

           

           

           

          最后一個函數regexp_replace

          REGEXP_REPLACE 函數是用另外一個值來替代串中的某個值。例如,可以用一個匹配數字來替代字母的每一次出現。REGEXP_REPLACE的格式如下所示

           

          語法:

          4.REGEXP_REPLACE與REPLACE函數相同,替換原字符串中的字符內容

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

           

           

          這個替換函數還是一個非常好用的。

          如我們在有一個字符串adfadfa (main) next 現在我們要把()替換成<>,這里我們可能想用replace就可以搞定了,但是我們現在做的是(之后必須有)這樣的()我們才替換把<>.

          select regexp_replace('adfadfa (main) next ','(\()([^\)]*)(\))','<\2>') from dual

          output: adfadfa <main> next

          這里還是一個\做為轉義字符。

           

          再來一個ip格式轉換的例子吧,我們一般的IP的格式是12.19.168.27現在要不足3位的補足前面為0,結果是012.019.168.027

          select regexp_replace(

          regexp_replace('12.19.168.27','([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})',

          '00\1.00\2.00\3.00\4') ,

          '([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}$)','\2\4\6\8')

          from dual

          output: 012.019.168.027

          這里我分成兩步來操作,regexp_replace('12.19.168.27','([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})',

          '00\1.00\2.00\3.00\4')我首先讓每個小字符串做添加0,這樣每個字符串都會大于3,再

          '([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}$)','\2\4\6\8')

          這整個字符串分成8段,這樣我們只要2、4、6、8這四個段就可以了。

           

           

          下面一個例子中,在每兩個字符之間插入一個空格符

          SELECT regexp_replace('YAHOO', '(.)', '\1 ') AS output FROM dual;

          Output: Y A H O O

          這個用一個循環的方式去操作,還蠻好的。

           

           

          select regexp_replace(

          regexp_replace('12.19.168.27','([^.]+)'

          ,'00\1')

          ,'([^.]*)([^.]{3})','\2')

          from dual

          接著剛才那個,我們可以把replace循環替換的方式來操作。

          posted on 2012-10-11 17:09 abing 閱讀(383) 評論(0)  編輯  收藏 所屬分類: oracle
          主站蜘蛛池模板: 万宁市| 维西| 江永县| 桐梓县| 屏东市| 嵊泗县| 潞西市| 泊头市| 英山县| 罗源县| 六盘水市| 偏关县| 吉林市| 河池市| 天祝| 肇州县| 赤水市| 龙州县| 邵阳市| 祥云县| 涡阳县| 泸溪县| 渭源县| 休宁县| 新干县| 淮安市| 沁源县| 芮城县| 滁州市| 启东市| 仲巴县| 新密市| 民丰县| 宜宾县| 兴义市| 赤峰市| 扶沟县| 章丘市| 永登县| 太仓市| 苏尼特右旗|