Welcome 微信登录

首页 / 数据库 / MySQL / Oracle正则表达式

需求:匹配手机号,第一位可以是+,可以没有+,后面的全部要是数字,如:+86135941566586136595585551356856455都是合法的。 +aa156945555aa1359556666aaddssdfdfsd都是不合法的。正则:[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_tablewhere regexp_like(field_1,"^1234")这个就是表示是以1234打头的字符串是不是有匹配的。这里和like的方式是一样的。  select * from test_tablewhere regexp_like(field_1,"^[12]234")这里多了一个[]这里做一个独立字符,这里表示是以1或2开始,并且接着是234这个里的字符就会是匹配的。  select * from test_tablewhere regexp_like(field_1,"^(欧阳|李)小二")这里我们就可以表达,这个查询一个姓是欧阳或李的,名字叫小二的字符串。这里多了一个()这个是做一个为字符串的方式来写的与[]刚好是对应。这里还有一个“|”来表示或的意思。  select * from test_tablewhere regexp_like(field_1,"^李[小]*二")这里我们就可以查询李小二或是李二,再或者是李小小二,都可以,这里我们需要讲一下是[]后面带了一个*,这个是表示0~无穷大 字符去匹配。这个[]我们还可以添加一个“+”来表示1~无穷大的字符去匹配,也可以更加精准一些,在[]后面{1,3}这里就是表示1个到3个相同字符的匹配。还有一个“?”来说表示1或是0个。  select * from test_tablewhere regexp_like(field_1,"李[^小]二")这里我们可以查询到姓李的,但是第二字不是“小”这个字。  select * from test_tablewhere regexp_like(field_1,"[0-9]")这里是表示我们查询字符串含有0-9的数字的字符串。  select * from test_tablewhere regexp_like(field_1,"[a-z]")这里是表示我们查询字符串含有a-z的小写字母的字符串。  select * from test_tablewhere regexp_like(field_1,"[A-z]")这里是表示我们查询字符串含有A-z的所有字母的字符串。  select * from test_tablewhere regexp_like(name,"[[:alpha:]]")这里是表示查询匹配任意字母,也包括中文字  select * from test_tablewhere regexp_like(name,"[[:alnum:]]")这里是表示查询匹配任意字母和数字  select * from test_tablewhere regexp_like(name,"[[:digit:]]")这里是表示查询匹配任意数字  Select * from test_tableWhere regexp_like(name,’of’,’i’)这里就是of不区分大小写  Select * from test_tableWhere 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 dualOutput: <main> 这里我们在<>中间去一个^>这样在匹配<之后,在向后查询的时候确保在匹配到>之前不再在有>,不然的话就要有可以出错的情况。  Select regexp_substr("asdfafd<main>da>fda","<[^<]+>") from dualOutput: <main>da>在这个例子中,我们在<main>之后还在da>,这样的话,如果我们没有添加^>,正则表达式就会向后继续去匹配,直到最后一个>为至,这样就会出现偏差  这个通常用来实现字符串的列传行select regexp_substr("123;234;345;456;567;678;789","[^;]+",1,rownum) from dualconnect 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 dualconnect 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.027select wm_concat(new_value) from (select lpad(regexp_substr("12.19.168.27","[^.]+",1,rownum) ,3,"0") new_value,rownumfrom dualconnect by rownum<5order by rownum)  来一个验证IP是数字是否正确select count(*) from(select lpad(regexp_substr("12.19.168.27","[^.]+",1,rownum) ,3,"0") new_value,rownumfrom dualconnect by rownum<5)where new_value>=0 and new_value<256having count(*) =4  来一个IP字符串格式转换成数字型IPselect sum(new_value*power(256,4-rm)) from (select regexp_substr("12.19.168.27","[^.]+",1,rownum) new_value,rownum rm from dualconnect 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 dualOutput: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_replaceREGEXP_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 dualoutput: adfadfa <main> next这里还是一个做为转义字符。 再来一个ip格式转换的例子吧,我们一般的IP的格式是12.19.168.27现在要不足3位的补足前面为0,结果是012.019.168.027select regexp_replace(regexp_replace("12.19.168.27","([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})","001.002.003.004") ,"([0-9]*)([0-9]{3}.)([0-9]*)([0-9]{3}.)([0-9]*)([0-9]{3}.)([0-9]*)([0-9]{3}$)","2468")from dualoutput: 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})","001.002.003.004")我首先让每个小字符串做添加0,这样每个字符串都会大于3,再"([0-9]*)([0-9]{3}.)([0-9]*)([0-9]{3}.)([0-9]*)([0-9]{3}.)([0-9]*)([0-9]{3}$)","2468")这整个字符串分成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","([^.]+)","001") ,"([^.]*)([^.]{3})","2")from dual接着刚才那个,我们可以把replace循环替换的方式来操作。Oracle kill session.delete 600w(1.25G)数据 1个多小时无结果Oracle普通表 临时表 awr统计分析相关资讯      Oracle基础教程 
  • Oracle块编程返回结果集详解  (11/10/2013 10:45:58)
  • Oracle基础教程之设置系统全局区  (08/22/2013 14:24:00)
  • Oracle基础教程知识点总结  (06/18/2013 07:43:32)
  • Oracle基础教程之tkprof程序详解  (10/22/2013 11:49:50)
  • Oracle基础教程之sqlplus汉字乱码  (07/18/2013 16:30:00)
  • Oracle 管理之 Linux 网络基础  (02/16/2013 18:37:35)
本文评论 查看全部评论 (0)
表情: 姓名: 字数