ORACLE10正規表示式(二)

2021-04-17 18:56:17 字數 2945 閱讀 5504

oracle10g增加的正規表示式功能!強!

oracle資料庫10g將正規表示式引入到sql語句中

oracle資料庫10g將正規表示式引入到sql語句中。

正規表示式是一種用於描述和操縱文字資料的功能強大的工具。事實上,正規表示式**於早期的低階unix 工具(如qed和ed),現在它已經變得幾乎無處不在,並且得到了各種廣泛的程式設計和指令碼語言、文字編輯器以及現在的oracle database 10g的支援。

什麼是正規表示式?

正規表示式都是關於模式的。它使你能夠使用文字資料來描述模式。一旦你能夠描述乙個模式,你就可以搜尋它,並且可以操縱它。

姓名街區編號 街區名稱

一旦你理解了這種模式,你一眼就可以辨認出位址。你的心裡習慣了每個資料元素的位置,因此不再需要標記出每個資料元素。你能夠識別乙個城市的名稱並不是因為它被標記「城市名稱」,而是因為它在模式中所處的位置。

識別模式取決於你。要描述你識別的模式,可以使用正規表示式。它們提供了一種簡潔的符號,你可以用這些符號來描述文字資料可找到的任何模式。oracle全新的正規表示式函式提供了操縱功能,使你能夠搜尋模式,提取符合模式的文字,以及將一種模式轉換為另一種模式。

支援表示式

最新的oracle資料庫版本oracle database 10g以下面四種新函式的形式實施正規表示式支援,這些函式在sql和pl/sql中也同樣適用:

regexp_like

regexp_replace

regexp_instr

regexp_substr

regexp_like是乙個布林函式或sql中的謂語,使你能夠識別出乙個列中包含符合給定模式的文字的行。它主要設計用於select語句的where子句中。

假設你有以下包含了關於密西根州立公園資訊的表:

create table michigan_park (

park_name varchar2 (40),

park_phone varchar2 (15),

description varchar2 (500)

);很多公園有多個**號碼,而且你發現令人有點惱火的是使用者將這麼多的**號碼記錄在description(描述)欄位中。你想要獲得有這種情況的所有公 園的列表。由於美國本地**號碼一般遵循***-***x模式, 因此你決定使用regexp_like來搜尋公園描述中的**號碼。清單 1 顯示了搜尋結果。

以下是清單 1中對regexp_like的呼叫:

where regexp_like(description,

'...-....');

第乙個引數是你想搜尋的字串,即description欄位。第二個引數表示搜尋的模式。在正規表示式中,句點(.)表示「任何字元」,所以這個表示式 代表任意三個字元接乙個破折號再跟任意四個字元。無論何時當被搜尋的文字中包含符合給定模式的文字時,該函式都會返回true(真)。在這種情況下,模式 匹配可以發生在字段值中的任何地方。

清單 1 中的三點-四點模式和結果提供了乙個很好的模糊分類的例子,這是你在使用正規表示式時必須接受的。首先,這種**號碼的模式在美國以外並沒有廣泛使用。我 在這裡使用該模式只是因為我知道我的資料與作為美國一部分的密西根州的公園相關,所以我認為這些公園會使用美國**號碼。 不過,請等一下!我的模式並沒有完全成功。為什麼muskallonge 湖州立公園也在輸出結果中?那個公園的描述中並沒有**號碼。

muskallonge 湖州立公園出現在清單1中是因為我選擇了乙個與我真正想要的結果鬆散匹配的模式。我沒有指明我的模式中除破折號外必須由數字組成。你看到了描述中的字串 「217-acre」嗎?這就是為什麼它會出現在結果中的原因:三個字元,乙個破折號,再跟四個字元。regexp_like給出了我所要求的結果。該函 數不知道資料的任何語義或意思。它並不知道我要找的是乙個**號碼,它也不知道「217-acre」並不是**號碼。

清單 1中出現乙個沒有**號碼的公園描述會帶來問題嗎?這取決於我計畫如何處理這些結果。如果我只是想知道**號碼,而且沒有太多錯誤的匹配,那麼我可以在閱 讀報告時忽略那些不匹配的結果。但是,如果我計畫以某種方式操縱這些**號碼,也許我就應該進一步改進我的模式。為此,我可以要求三個和四個數字而不是字 符,如下所示:

where regexp_like(description,

'[0-9]-[0-9]');

到這裡就可以結束了,但我沒有這樣做。看看清單 1中的資料,你會看到一些使用者明顯喜歡用句點來分隔**號碼的數字組。為了最大限度地提高查詢效率,我應該允許在數字組之間使用破折號(-)或句點(.),如下所示:

where regexp_like(description,

'[0-9][-.][0-9]');

讓我們來解釋一下這個表示式的每個部分:

[0-9]匹配任何數字

重複前乙個元素三次。

[-.] 匹配乙個破折號或乙個句點。

[0-9]匹配任何數字。

前乙個元素最少和最多都必須出現4次。

這看起來好象是個比較合理的嚴格表示式,因為我不希望有太多錯誤的匹配。清單 2顯示了查詢結果。然而,使用正規表示式來處理文字永遠都是不精確的方法。如果某個描述為「見參考手冊的第997-1012頁」,那麼這個描述也會與我建 立的表示式相匹配。正規表示式只匹配模式,它們只能匹配模式,不能辨別意思。

關於索引

不要讓正規表示式求值可能不會使用索引這個事實阻止你在查詢中使用正規表示式。正規表示式實在是太有用了,千萬不要把它棄於你的工具箱之外。如果乙個正則 表示式正是你解決手頭問題所需要的,那就是使用它。只是心裡要清楚它的潛在開銷。另外還要考慮到,在索引不相關的情況下正規表示式是非常有用的。例如,看 到描述欄位中**號碼的多樣性,我可能選擇將park_phone欄位限制為乙個單一的格式,即在美國使用的區域**和**號碼(***) ***-***x模式,如清單 3所示。

清單 3中正規表示式兩端的脫字符號(^)和美元符號($)是用於防止前導空格和尾部空格儲存在park_phone欄位中的錨點。脫字符號標誌著表示式字段值的開始,而美元符號則標誌著表示式的結束。這種標定可以避免前導或字尾空格。

ORACLE10正規表示式(一)

oracle 8 和oracle 9i中缺乏靈活性的sql 正規表示式最終在oracle 10g中得到了解決。oracle 資料庫目前內建了符合posix 標準的正規表示式。四個新的函式分別是 regexp like regexp instr regexp substr 和 regexp repla...

oracle 正規表示式

with temp as select br.777 1 a from dual union all select bs.6 175 a from dual union all select d.140 supplement 1 a from dual union all select e.191 ...

oracle正規表示式

在資料庫可直接執行下面語句,但在程式中不能執行,regexp like t.ipaddress,25 0 5 2 0 4 0 9 01 0 9 0 9 25 0 5 2 0 4 0 9 01 0 9 0 9 報錯有特殊字元 在句末再加乙個 改為 regexp like t.ipaddress,25 ...