原文:http://www.jb51.net/article/31227.htmgit
正則表達式具備強大、便捷、高效的文本處理功能。可以添加、刪除、分析、疊加、插入和修整各類類型的文本和數據。Oracle從10g開始支持正則表達式正則表達式
下面經過一些例子來講明使用正則表達式來處理一些工做中常見的問題。 express
1. 緩存
REGEXP_SUBSTR oracle
REGEXP_SUBSTR 函數使用正則表達式來指定返回串的起點和終點,返回與source_string 字符集中的VARCHAR2 或CLOB 數據相同的字符串。 ide
語法: 函數
--1.REGEXP_SUBSTR與SUBSTR函數相同,返回截取的子字符串 測試
REGEXP_SUBSTR(srcstr, pattern [, position [, occurrence [, match_option]]]) spa
注: 操作系統
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('@@/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('@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」
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個字符開始匹配
1
第1次出現符合匹配結果的字符
i
表示區分大小寫
1.3其餘一些匹配樣式
查找網頁地址信息
SELECT regexp_substr('Go to http://www.oracle.com/products and click on database', 'http://([[:alnum:]]+\.?){3,4}/?') RESULT
FROM dual
Output: http://www.oracle.com
其中:
http://
表示匹配字符串「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
Oracle正則表達式(regularexpression)
元字符
字符含義
舉例說明
^
匹配字符串的開始位置(在[]中使用,此時它表示不接受該字符集合。
^a:匹配以a開始的字符串
[^a]:匹配不含a的字符串
-
當使用在a-m表示範圍;
當使用在第一個字符時表示
連字符串,如[-abc]
$
匹配字符結束位置
‘a$':匹配以a結束的字符串
.
匹配除換行符 n以外的任何單字符。
?
匹配前面的子表達式零次或一次
tr(y(ing)?):能夠表示try或者trying
*
匹配前面的子表達式零次或屢次
+
匹配前面的子表達式一次或屢次
()
標記一個子表達式的開始和結束位置
a(b)*能夠匹配
ab,abb,abbb,youabb
(c|d)匹配c或d
[]
標記一箇中括號表達式
[cd]匹配選擇c或d等同於
(c|d)。匹配的是單字符,[^cd]是匹配c,d以外的單字符。
[a-z]表示全部小寫字母
{m,n}
m= <出現次數 <=n,'{m}'表示出現m次,'{m,}'表示至少出現m次。
|
表示或者的關係。指明兩項之間的一個選擇
字符簇
字符含義
[[:alpha:]]
任何字母。
[[:digit:]]
[[:digit:]] 任何數字。
[[:alnum:]]
任何字母和數
[[:space:]]
任何白字符。
[[:upper:]]
任何大寫字母。
[[:lower:]]
任何小寫字母。
[[:punct:]]
任何標點符號。
[[:xdigit:]]
任何16進制的數字,至關於[0-9a-fA-F]。
Oracle支持正則表達式的內置函數
名稱
語法
備註
REGEXP_LIKE
REGEXP_LIKE
(source_string,
pattern
[, match_parameter]
)
source_string:
源字符串
Pattern:
正則表達式
match_parameter:
匹配模式(i:不區分大小寫;c:區分大小寫;n:容許使用能夠匹配任意字符串的操做符;m:將x做爲一個包含多行的字符串。
REGEXP_REPLACE
REGEXP_REPLACE
(source_string,
pattern
[,replace_string]
[,position]
[,occurtence]
[,match_parameter]
)
replace_string:
用於替換的字符串
Position:
開始搜索的起始位置
occurtence
指定替換第n次出現字符串
其餘同上。
REGEXP_SUBSTR
REGEXP_SUBSTR
(source_string, pattern
[,position
[,occurrence
[,match_parameter]]]
)
Position:
指定在字符串中準確位置,默認爲1
Occurrence:
指定在源字符串匹配過程當中相對其餘字符串,哪一個字符串應該匹配。例如
select regexp_substr('The zip code
80831 is for falcon, co',
'[[:alpha:]]{3,}', 1, 3)
from dual;
結果選擇的是code而非The或zip。
REGEXP_INSTR
REGEXP_INSTR
(source_string,
pattern
[,start_position
[,occurrence
[,return_option
[,match_parameter]]]]
)
start_position:
開始搜索位置
Occurrence:
第n次出現pattern,默認爲1
return_option:
0:pattern的起始位置
1:pattern下一個字符起始位置
默認爲0
REGEXP_COUNT
REGEXP_COUNT
(source_string,
pattern
[[,start_position]
[,match_parameter]])
11g新增的函數,表示pattern在原字符串中出現的次數
start_position:
開始搜索的位置
Oracle支持正則表達式函數舉例。
Regexp_substr:用來提取一個字符串的一部分。
Regexp_substr('first filed, second filed, thirdfiled', ', [^,]*,')
Pattern爲', [^,]*,'表示以,開始逗號,中間空一個格,連續0或多個非逗號字符,最後仍是逗號,這樣,返回則爲', second filed,'。
-------------------------------------------------------------------------------
Regexp_instr:用來pattern的起始位置。
若有一組地址,返回郵編的位置
regexp_instr('Jone Smith,10045 Berry Lane,SanJoseph,CA
91234-1234','[[:digit:]]{5}([-[[:digit:]]{4}])?$')
顯然結果位置是91234-1234對應的起始位置。
-------------------------------------------------------------------------------
Regexp_replace:用來將pattern替換成須要替換的字符串,相比傳統的replace函數,該函數相比較靈活。例如:
'Jone smith'中有三個空格,而'Jone smith'有2個空格,要將中間的空格改成一個空格,使用replace就要使用2次,而是用正則表達式,咱們就就能夠將pattern設計爲
'( ){2,}'這樣
regexp_replace(mc,'( ){2,}',' ')
-------------------------------------------------------------------------------
regexp_like是加強版的like,能夠包含_和%通配符,使用在where條件中。
正則表達式特性---後向引用
經過將自表達式匹配的內容緩存到緩衝區中,從左相右進行編號,以/digit(digit爲1-9)。而子表達式用圓括號表示。
1.在regexp_replace中應用:
將字符串'aa bb cc'反寫成'cc bb aa'則能夠設計以下:
regexp_replace('aa bbcc','(.*) (.*) (.*)','\3 \2 \1')
(.*)則表示任何一個字符串組合,三個這樣的組合用空格隔開,與源字符串吻合,\1,\2,\3則分別存儲了三個字表達式的值,這樣咱們就可使用這個達到目的。
2.在regexp_substr中應用:
查找被空格隔開的重複字母數字值
regexp_substr('the finaltest is is the implention','([[:alnum:]]+)([[:space:]]+)\1')
返回結果爲is is 。([[:alnum:]]+)([[:space:]]+)返回不少字符串,可是增長一個\1就表示連續返回兩個一樣字符串,這樣就把重複的串給找出來。
補充
oracle的正則表達式
本文摘要:
10g正則表達式提升了SQL靈活性。
無關的空白檢測,或者分解多個正則組成的字符串等問題。
10g支持正則表達式的四個新函數分別是:REGEXP_LIKE、REGEXP_INSTR、REGEXP_SUBSTR、和REGEXP_REPLACE。
正則表達式代替了老的百分號(%)和通配符(_)字符。
匹配輸入字符串的開始位置,在方括號表達式中使用,此時它表示不接受該字符集合。
匹配前面的子表達式零次或一次。
目前,正則表達式已經在不少軟件中獲得普遍的應用,包括*nix(Linux, Unix等),HP等操做系統,PHP,C#,Java等開發環境。
Oracle 10g正則表達式提升了SQL靈活性。有效的解決了數據有效性, 重複詞的辨認, 無關的空白檢測,或者分解多個正則組成
的字符串等問題。
Oracle 10g支持正則表達式的四個新函數分別是:REGEXP_LIKE、REGEXP_INSTR、REGEXP_SUBSTR、和REGEXP_REPLACE。
它們使用POSIX 正則表達式代替了老的百分號(%)和通配符(_)字符。
特殊字符:
'^' 匹配輸入字符串的開始位置,在方括號表達式中使用,此時它表示不接受該字符集合。
'$' 匹配輸入字符串的結尾位置。若是設置了 RegExp 對象的 Multiline 屬性,則 $ 也匹配 'n' 或 'r'。
'.' 匹配除換行符 n以外的任何單字符。
'?' 匹配前面的子表達式零次或一次。
'*' 匹配前面的子表達式零次或屢次。
'+' 匹配前面的子表達式一次或屢次。
'( )' 標記一個子表達式的開始和結束位置。
'[]' 標記一箇中括號表達式。
'{m,n}' 一個精確地出現次數範圍,m=<出現次數<=n,'{m}'表示出現m次,'{m,}'表示至少出現m次。
'|' 指明兩項之間的一個選擇。例子'^([a-z]+|[0-9]+)$'表示全部小寫字母或數字組合成的字符串。
num 匹配 num,其中 num 是一個正整數。對所獲取的匹配的引用。
正則表達式的一個頗有用的特色是能夠保存子表達式之後使用, 被稱爲Backreferencing. 容許複雜的替換能力
如調整一個模式到新的位置或者指示被代替的字符或者單詞的位置. 被匹配的子表達式存儲在臨時緩衝區中,
緩衝區從左到右編號, 經過數字符號訪問。 下面的例子列出了把名字 aa bb cc 變成
cc, bb, aa.
Select REGEXP_REPLACE('aa bb cc','(.*) (.*) (.*)', '3, 2, 1') FROM dual;
REGEXP_REPLACE('ELLENHILDISMIT
cc, bb, aa
'' 轉義符。
字符簇:
[[:alpha:]] 任何字母。
[[:digit:]] 任何數字。
[[:alnum:]] 任何字母和數字。
[[:space:]] 任何白字符。
[[:upper:]] 任何大寫字母。
[[:lower:]] 任何小寫字母。
[[:punct:]] 任何標點符號。
[[:xdigit:]] 任何16進制的數字,至關於[0-9a-fA-F]。
各類操做符的運算優先級
轉義符
(), (?:), (?=), [] 圓括號和方括號
*, +, ?, {n}, {n,}, {n,m} 限定符
^, $, anymetacharacter 位置和順序
| 「或」操做
--測試數據
create table test(mc varchar2(60));
insert into test values('112233445566778899');
insert into test values('22113344 5566778899');
insert into test values('33112244 5566778899');
insert into test values('44112233 5566 778899');
insert into test values('5511 2233 4466778899');
insert into test values('661122334455778899');
insert into test values('771122334455668899');
insert into test values('881122334455667799');
insert into test values('991122334455667788');
insert into test values('aabbccddee');
insert into test values('bbaaaccddee');
insert into test values('ccabbddee');
insert into test values('ddaabbccee');
insert into test values('eeaabbccdd');
insert into test values('ab123');
insert into test values('123xy');
insert into test values('007ab');
insert into test values('abcxy');
insert into test values('The final test is is is how to find duplicate words.');
commit;
1、REGEXP_LIKE
select * from test where regexp_like(mc,'^a{1,3}');
select * from test where regexp_like(mc,'a{1,3}');
select * from test where regexp_like(mc,'^a.*e$');
select * from test where regexp_like(mc,'^[[:lower:]]|[[:digit:]]');
select * from test where regexp_like(mc,'^[[:lower:]]');
Select mc FROM test Where REGEXP_LIKE(mc,'[^[:digit:]]');
Select mc FROM test Where REGEXP_LIKE(mc,'^[^[:digit:]]');
2、REGEXP_INSTR
Select REGEXP_INSTR(mc,'[[:digit:]]$') from test;
Select REGEXP_INSTR(mc,'[[:digit:]]+$') from test;
Select REGEXP_INSTR('The price is $400.','$[[:digit:]]+') FROM DUAL;
Select REGEXP_INSTR('onetwothree','[^[[:lower:]]]') FROM DUAL;
Select REGEXP_INSTR(',,,,,','[^,]*') FROM DUAL;
Select REGEXP_INSTR(',,,,,','[^,]') FROM DUAL;
3、REGEXP_SUBSTR
SELECT REGEXP_SUBSTR(mc,'[a-z]+') FROM test;
SELECT REGEXP_SUBSTR(mc,'[0-9]+') FROM test;
SELECT REGEXP_SUBSTR('aababcde','^a.*b') FROM DUAL;
4、REGEXP_REPLACE
Select REGEXP_REPLACE('Joe Smith','( ){2,}', ',') AS RX_REPLACE FROM dual;
Select REGEXP_REPLACE('aa bb cc','(.*) (.*) (.*)', '3, 2, 1') FROM dual;
SQL> select * from test;
ID MC
-------------------- ------------------------------------------------------------
A AAAAA
a aaaaa
b bbbbb
SQL> select * from test where regexp_like(id,'b','i'); --不區分數據大小寫
ID MC
-------------------- ------------------------------------------------------------
b bbbbb
#End