使用正規表示式編寫更好的SQL

2021-04-17 06:49:33 字數 4379 閱讀 6162

oracle database 10g 的乙個新特性大大提高了您搜尋和處理字元資料的能力。這個特性就是正規表示式,是一種用來描述文字模式的表示方法。很久以來它已在許多程式語言和大量 unix 實用工具中出現過了。

oracle 的正規表示式的實施是以各種 sql 函式和乙個 where 子句操作符的形式出現的。如果您不熟悉正規表示式,那麼這篇文章可以讓您了解一下這種新的極其強大然而表面上有點神秘的功能。已經對正規表示式很熟悉的讀者可以了解如何在 oracle sql 語言的環境中應用這種功能。

什麼是正規表示式?

正規表示式由乙個或多個字元型文字和/或元字元組成。在最簡單的格式下,正規表示式僅由字元文字組成,如正規表示式 cat。它被讀作字母 c,接著是字母 a 和 t,這種模式匹配 cat、location 和 catalog 之類的字串。元字元提供演算法來確定 oracle 如何處理組成乙個正規表示式的字元。當您了解了各種元字元的含義時,您將體會到正規表示式用於查詢和替換特定的文字資料是非常強大的。

用 oracle database 10g 使用正規表示式

您可以使用最新引進的 oracle sql regexp_like 操作符和 regexp_instr、regexp_substr 以及 regexp_replace 函式來發揮正規表示式的作用。您將體會到這個新的功能如何對 like 操作符和 instr、substr 和 replace 函式進行了補充。實際上,它們類似於已有的操作符,但現在增加了強大的模式匹配功能。被搜尋的資料可以是簡單的字串或是儲存在資料庫字元列中的大量文字。正規表示式讓您能夠以一種您以前從未想過的方式來搜尋、替換和驗證資料,並提供高度的靈活性。

正規表示式的基本例子

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

預設情況下,乙個正規表示式中的乙個單獨的字元或字元列表只匹配一次。為了指示在乙個正規表示式中多次出現的乙個字元,您可以使用乙個量詞,它也被稱為重複操作符。.如果您想要得到從字母 a 開始並以字母 b 結束的匹配模式,則您的正規表示式看起來像這樣:^a.*b$。* 元字元重複前面的元字元 (.) 指示的匹配零次、一次或更多次。like 操作符的等價的模式是 a%b,其中用百分號 (%) 來指示任意字元出現零次、一次或多次。

表 2 給出了重複操作符的完整列表。注意它包含了特殊的重複選項,它們實現了比現有的 like 萬用字元更大的靈活性。如果您用圓括號括住乙個表示式,這將有效地建立乙個可以重複一定次數的子表示式。例如,正規表示式 b(an)*a 匹配 ba、bana、banana、yourbananasplit 等。

oracle 的正規表示式實施支援 posix (可移植作業系統介面)字元類,參見表 3 中列出的內容。這意味著您要查詢的字元型別可以非常特別。假設您要編寫一條僅查詢非字母字元的 like 條件 — 作為結果的 where 子句可能不經意就會變得非常複雜。

posix 字元類必須包含在乙個由方括號 () 指示的字元列表中。例如,正規表示式 [[:lower:]] 匹配乙個小寫字母字元,而 [[:lower:]] 匹配五個連續的小寫字母字元。

除 posix 字元類之外,您可以將單獨的字元放在乙個字元列表中。例如,正規表示式 ^ab[cd]ef$ 匹配字串 abcef 和 abdef。必須選擇 c 或 d。

除脫字元 (^) 和連字元 (-) 之外,字元列表中的大多數元字元被認為是文字。正規表示式看起來很複雜,這是因為一些元字元具有隨上下文環境而定的多重含義。^ 就是這樣一種元字元。如果您用它作為乙個字元列表的第乙個字元,它代表乙個字元列表的非。因此,[^[:digit:]] 查詢包含了任意非數字字元的模式,而 ^[[:digit:]] 查詢以數字開始的匹配模式。連字元 (-) 指示乙個範圍,正規表示式 [a-m] 匹配字母 a 到字母 m 之間的任意字母。但如果它是乙個字元行中的第乙個字元(如在 [-afg] 中),則它就代表連字元。

之前的乙個例子介紹了使用圓括號來建立乙個子表示式;它們允許您通過輸入更替元字元來輸入可更替的選項,這些元字元由豎線 (|) 分開。

例如,正規表示式 t(a|e|i)n 允許字母 t 和 n 之間的三種可能的字元更替。匹配模式包括如 tan、ten、tin 和 pakistan 之類的字,但不包括 teen、mountain 或 tune。作為另一種選擇,正規表示式 t(a|e|i)n 也可以表示為乙個字元列表 t[aei]n。表 4 彙總了這些元字元。雖然存在更多的元字元,但這個簡明的概述足夠用來理解這篇文章使用的正規表示式。

regexp_like 操作符

regexp_like 操作符向您介紹在 oracle 資料庫中使用時的正規表示式功能。表 5 列出了 regexp_like 的語法。

下面的 sql 查詢的 where 子句顯示了 regexp_like 操作符,它在 zip 列中搜尋滿足正規表示式 [^[:digit:]] 的模式。它將檢索 zipcode 表中的那些 zip 列值包含了任意非數字字元的行。

select zip

from zipcode

where regexp_like(zip, '[^[:digit:]]')

zip-----

ab123

123xy

007ab

abcxy

這個正規表示式的例子僅由元字元組成,更具體來講是被冒號和方括號分隔的 posix 字元類 digit。第二組方括號(如 [^[:digit:]] 中所示)包括了乙個字元類列表。如前文所述,需要這樣做是因為您只可以將 posix 字元類用於構建乙個字元列表。

regexp_instr 函式

select regexp_instr('joe **ith, 10045 berry lane, san joseph, ca 91234',

'[[:digit:]]$')

as rx_instr

from dual

rx_instr

----------

45 編寫更複雜的模式

select regexp_instr('joe **ith, 10045 berry lane, san joseph, ca 91234-1234',

' [[:digit:]](-[[:digit:]])?$')

as starts_at

from dual

starts_at

----------

44 在這個示例中,括弧裡的子表示式 (-[[:digit:]]) 將按 ? 重複操作符的指示重複零次或一次。此外,企圖用傳統的 sql 函式來實現相同的結果甚至對 sql 專家也是乙個挑戰。為了更好地說明這個正規表示式示例的不同組成部分,表 7 包含了乙個對單個文字和元字元的描述。

regexp_substr 函式

select regexp_substr('first field, second field , third field',

', [^,]*,')

from dual

regexp_substr('fir

------------------

, second field ,

regexp_replace 函式

讓我們首先看一下傳統的 replace sql 函式,它把乙個字串用另乙個字串來替換。假設您的資料在正文中有不必要的空格,您希望用單個空格來替換它們。利用 replace 函式,您需要準確地列出您要替換多少個空格。然而,多餘空格的數目在正文的各處可能不是相同的。下面的示例在 joe 和 **ith 之間有三個空格。replace 函式的引數指定要用乙個空格來替換兩個空格。在這種情況下,結果在原來的字串的 joe 和 **ith 之間留下了乙個額外的空格。

select replace('joe **ith',' ', ' ')

as replace

from dual

replace

---------

joe **ith

regexp_replace 函式把替換功能向前推進了一步,其語法在表 9 中列出。以下查詢用單個空格替換了任意兩個或更多的空格。( ) 子表示式包含了單個空格,它可以按 的指示重複兩次或更多次。

select regexp_replace('joe **ith',

'( )', ' ')

as rx_replace

from dual

rx_replace

----------

joe **ith

Linux正規表示式 編寫正規表示式

為了所有實用化的用途,你可以通過使用程式產生正確的結果。然而,並不意味著程式總是如你所願的那樣正確地工作。多數情況下,如果程式不能產生想要的輸出,可以斷定真正的問題 排除輸入或語法錯誤 在於如何描述想要的東西。換句話說,應該考慮糾正問題的地方是描述想要的結果的表示式。表示式不完整或者公式表示得不正確...

編寫正規表示式

是不是感覺有點無從下手?別慌,慢慢來。通過對比網頁和網頁 我們確認資訊特徵。房產名稱 急降60萬 急賣全款客戶來 寶山二村好位置複製該資訊,到html檔案中通過ctrl f查詢該資訊,然後認真檢視 房產名稱 前後的字元特徵 前面的字元特徵 後面的字元特徵 現在對照房產名稱前後的字元特徵編寫正規表示式...

sql正規表示式 SQL中的正規表示式

sql正規表示式 sql中的正規表示式 sql的查詢語句中,有時會需要引進正規表示式為其複雜搜尋指定模式。下面給出一些 regexp 在mysql 語句中應用 非全部 1 匹配字串的開始部分。mysql select fo nfo regexp fo 0mysql select fofo regex...