专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »数据库 » oracle正则表达式:在Oracle使用正规表达式编写更好的SQL语句 »正文

oracle正则表达式:在Oracle使用正规表达式编写更好的SQL语句

来源: 发布时间:星期四, 2009年2月5日 浏览:0次 评论:0
="t18"> Oracle Database 10g 个新特性大大提高了您搜索和处理数据能力这个特性就是正规表达式种用来描述文本模式表示思路方法很久以来它已在许多编程语言和大量 UNIX 实用工具中出现过了
  
  Oracle 正规表达式实施是以各种 SQL 个 WHERE 子句操作符形式出现假如您不熟悉正规表达式那么这篇文章可以让您了解下这种新极其强大然而表面上有点神秘功能已经对正规表达式很熟悉读者可以了解如何在 Oracle SQL 语言环境中应用这种功能
  
  什么是正规表达式?
  
  正规表达式由个或多个型文字和/或元组成在最简单格式下正规表达式仅由文字组成如正规表达式 cat它被读作字母 c接着是字母 a 和 t这种模式匹配 cat、location 和 catalog 的类提供算法来确定 Oracle 如何处理组成个正规表达式当您了解了各种元含义时您将体会到正规表达式用于查找和替换特定文本数据是非常强大
  
  验证数据、识别重复要害字出现、检测不必要空格或分析串只是正规表达式许多应用中部分您可以用它们来验证电话号码、邮政编码、电子邮件地址、社会安全号码、IP 地址、文件名和路径名等格式此外您可以查找如 Html 标记、数字、日期的类模式或任意文本数据中符合任意模式任何事物并用其它模式来替换它们
  
  用 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 结尾条 3个字母则您必须对正规表达式进行定位号 (^) 元指示开始而美元符号 ($) 指示结尾(参见表 1)因此 正规表达式 ^a.b$ 匹配串 aab、abb 或 axb将这种方式和 LIKE ²Ù×÷·&UCirc;提供类似模式匹配 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:]]{5} 匹配 5个连续小写字母
  
  除 POSIX 类的外您可以将单独放在列表中例如正规表达式 ^ab[cd]ef$ 匹配串 abcef 和 abdef必须选择 c 或 d
  
  除脱 (^) 和连 (-) 的外列表中大多数元被认为是文字正规表达式看起来很复杂这是些元具有随上下文环境而定多重含义^ 就是这样种元假如您用它作为列表它代表列表因此[^[:digit:]] 查找包含了任意非数字模式而 ^[[:digit:]] 查找以数字开始匹配模式 (-) 指示个范围正规表达式 [a-m] 匹配字母 a 到字母 m 的间任意字母但假如它是行中(如在 [-afg] 中)则它就代表连
  
  的前个例子介绍了使用圆括号来创建个子表达式;它们答应您通过输入更替元来输入可更替选项这些元由竖线 分开
  
  例如正规表达式 t(aei)n 答应字母 t 和 n 的间 3种可能更替匹配模式包括如 tan、ten、tin 和 Pakistan 的类但不包括 teen、mountain 或 tune作为另种选择正规表达式 t(aei)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第 2组方括号(如 [^[:digit:]] 中所示)包括了类列表如前文所述需要这样做是您只可以将 POSIX 类用于构建列表
  
  REGEXP_INSTR
  
  这个返回个模式起始位置因此它功能非常类似于 INSTR REGEXP_INSTR 语法在表 6 中给出这两个的间主要区别是REGEXP_INSTR 让您指定种模式而不是个特定搜索串;因而它提供了更多功能接下来举例使用 REGEXP_INSTR 来返回串 Joe Smith, 10045 Berry Lane, San Joseph, CA 91234 中 5位邮政编码模式起始位置假如正规表达式被写为 [[:digit:]]{5}则您将得到门牌号起始位置而不是邮政编码 10045 是第次出现 5个连续数字因此您必须将表达式定位到该行末尾正如 $ 元所示将显示邮政编码起始位置而不管门牌号数字个数
  
  SELECT REGEXP_INSTR('Joe Smith, 10045 Berry Lane, San Joseph, CA 91234',
  '[[:digit:]]{5}$')
  AS rx_instr
  FROM dual
  RX_INSTR
  ----------
  45
  
  编写更复杂模式
  
  让我们在前个例子邮政编码模式上展开以便包含个可选 4位数字模式模式现在可能看起来像这样:[[:digit:]]{5}(-[[:digit:]]{4})?$假如您串以 5 位邮政编码或 5 位 + 4 位邮政编码格式结束则您将能够显示该模式起始位置
  
  SELECT REGEXP_INSTR('Joe Smith, 10045 Berry Lane, San Joseph, CA 91234-1234',
  ' [[:digit:]]{5}(-[[:digit:]]{4})?$')
  AS starts_at
  FROM dual
  STARTS_AT
  ----------
  44
  
  在这个举例中括弧里子表达式 (-[[:digit:]]{4}) 将按 ? 重复操作符指示重复零次或此外企图用传统 SQL 来实现相同结果甚至对 SQL 专家也是个挑战为了更好地介绍说明这个正规表达式举例区别组成部分表 7 包含了个对单个文字和元描述
  
  REGEXP_SUBSTR
  
  ·Ç³£ÀàËÆÓÚ SUBSTR REGEXP_SUBSTR 用来提取部分表 8 显示了这个新语法在下面举例中匹配模式 [^,]* 串将被返回该正规表达式搜索其后紧跟着空格个逗号;然后按 [^,]* 指示搜索零个或更多个不是逗号最后查找另个逗号这种模式看起来有点像个用逗号分隔
  
  SELECT REGEXP_SUBSTR('first field, second field , third field',
  ', [^,]*,')
  FROM dual
  REGEXP_SUBSTR('FIR
  ------------------
  , second field ,
  
  REGEXP_REPLACE
  
  让我们首先看下传统 REPLACE SQL 它把串用另串来替换假设您数据在正文中有不必要空格您希望用单个空格来替换它们利用 REPLACE 您需要准确地列出您要替换多少个空格然而多余空格数目在正文各处可能不是相同下面举例在 Joe 和 Smith 的间有 3个空格REPLACE 参数指定要用个空格来替换两个空格在这种情况下结果在原来 Joe 和 Smith 的间留下了个额外空格
  
  SELECT REPLACE('Joe Smith',' ', ' ')
  AS replace
  FROM dual
  REPLACE
  ---------
  Joe Smith
  
  REGEXP_REPLACE 把替换功能向前推进了其语法在表 9 中列出以下查询用单个空格替换了任意两个或更多空格( ) 子表达式包含了单个空格它可以按 {2,} 指示重复两次或更多次
  
  SELECT REGEXP_REPLACE('Joe Smith',
  '( ){2,}', ' ')
  AS RX_REPLACE
  FROM dual
  RX_REPLACE
  ----------
  Joe Smith
  


相关文章

读者评论

发表评论

  • 昵称:
  • 内容: