需求:(x)
匚w手机PW一位可以是+Q可以没?Q后面的全部要是数字Q如Q?/p>
+861359415665
8613659558555
1356856455
都是合法的?/p>+aa156945555
aa1359556666
aaddssdfdfsd
都是不合法的?/p>
正则Q?/p>
- SQL> SELECT * FROM DUAL WHERE regexp_like('+333333' ,'^[\+]*[[:digit:]]+'); --?转义或者不转义Q结果是一L(fng)
-
- DUMMY
- -----
- X
[sql]
- SQL> SELECT * FROM DUAL WHERE regexp_like('aa333333' ,'^[+]*[[:digit:]]+');
-
- DUMMY
- -----
解释Q?/p>
1.^代表开始,*表示出现0ơ或多次Q?表示出现1ơ或多次Q[:digit:]代表0-9的纯数字Q还?代表以什么结,如果是[[:digit:]]+$代表以数字结)(j)。该正则的意思就是:(x)
?0ơ或多次开_(d)紧接着后面数字出现一ơ或多次Q即一定要有数字)(j)?/p>
2.dual表中Q永q只?行记录。查询出dual中有记录Q证明where条g成立Q反之不成立?/p>
先前写了一个错误的正则Q?/p>
注意Q就只少了一个代表开始符L(fng)^。少了这个符P说明q个正则的意思是Q?/p>
+出现0ơ或多次Q即+可以出现Q可以不出现Q!Q,紧后面的数字出现1ơ或多次。前面已l?可以出现0ơ了Q证明没?也可以,那么是只要字符串中有数?+aa111aQaass11111……)Q这个正则恒成立Q错误深重啊Q!
Oracle正则表达式的应用by 温州--名次
在oracle里正则表辑ּ有四个函数可用,分别是regexp_like、regexp_substr、regexp_instr 和regexp_replace。这里在我们oracle 10g里灵zd用?/p>
先来单介l一下正则表辑ּ的内容,正则表达式是做ؓ(f)快速查询的文本内容的,在linux应用比较多,首先Q行的v始与l束 “^”q个字符是表C只查找行首的内宏V?#8220;$”q个字符只查找行末的内容。接下来?#8220;^”q可以做Z个排除字W来使用。还是用例子来做一个演C比较明了一下?/p>
q里我用regexp_likeq个函数来做Q这样可以我们^时会(x)使用的比较多?/p>
select * from test_table
where regexp_like(field_1,'^1234')
q个是表示是以1234打头的字W串是不是有匚w的。这里和like的方式是一L(fng)?/p>
select * from test_table
where regexp_like(field_1,'^[12]234')
q里多了一个[]q里做一个独立字W,q里表示是以1?开始,q且接着?34q个里的字符׃(x)是匹配的?/p>
select * from test_table
where regexp_like(field_1,'^(Ƨ阳|?二')
q里我们可以表达,q个查询一个姓是欧x李的Q名字叫二的字W串。这里多了一个(Q这个是做一个ؓ(f)字符串的方式来写的与[]刚好是对应?/p>
q里q有一?#8220;|”来表C或的意思?/p>
select * from test_table
where regexp_like(field_1,'^李[]*?)
q里我们可以查询李二或是李二Q再或者是李小二Q都可以Q这里我们需要讲一下是[]后面带了一?Q这个是表示0~无穷?字符d配。这个[]我们q可以添加一?#8220;+”来表C?~无穷大的字符d配,也可以更加精准一些,在[]后面{1,3}q里是表示1个到3个相同字W的匚w。还有一?#8220;?”来说表示1或是0个?/p>
select * from test_table
where regexp_like(field_1,'李[^]?)
q里我们可以查询到姓李的Q但是第二字不是“?#8221;q个字?/p>
select * from test_table
where regexp_like(field_1,'[0-9]')
q里是表C我们查询字W串含有0-9的数字的字符丌Ӏ?/p>
select * from test_table
where regexp_like(field_1,'[a-z]')
q里是表C我们查询字W串含有a-z的小写字母的字符丌Ӏ?/p>
select * from test_table
where regexp_like(field_1,'[A-z]')
q里是表C我们查询字W串含有A-z的所有字母的字符丌Ӏ?/p>
select * from test_table
where regexp_like(name,'[[:alpha:]]')
q里是表C查询匹配Q意字母,也包括中文字
select * from test_table
where regexp_like(name,'[[:alnum:]]')
q里是表C查询匹配Q意字母和数字
select * from test_table
where regexp_like(name,'[[:digit:]]')
q里是表C查询匹配Q意数?/p>
Select * from test_table
Where regexp_like(name,’of’,’i’)
q里是of不区分大写
Select * from test_table
Where regexp_like(name,’^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$’)
q样我们可以查询是不是ip格式
接下来介l一下regexp_substr
q个也是一个非常实用的一个函?/p>
REGEXP_SUBSTR与SUBSTR函数相同Q返回截取的子字W串
REGEXP_SUBSTR(srcstr, pattern [, position [, occurrence [, match_option]]])
注:(x)
srcstr 源字W串
pattern 正则表达式样?/p>
position 开始匹配字W位|?/p>
occurrence 匚w出现ơ数
match_option 匚w选项Q区分大写Q?/p>
SELECT regexp_substr('1PSN/231_3253/ABc', '[[:alnum:]]+') FROM dual;
Output: 1PSN
[[:alnum:]]+ 表示匚w1个或者多个字母或数字字符
SELECT regexp_substr('1PSN/231_3253/ABc', '[[:alnum:]]+', 1, 2) FROM dual;
Output: 231
与上面一个例子相比,多了两个参数
1 表示从源字符串的W一个字W开始查扑?/p>
2 表示W?ơ匹配到的字W串Q默认值是“1”Q如上例Q?/p>
select regexp_substr('@@/231_3253/ABc','@*[[:alnum:]]+') from dual;
Output: 231
@* 表示匚w0个或者多个@
[[:alnum:]]+ 表示匚w1个或者多个字母或数字字符
注意Q需要区?#8220;+”?#8220;*”的区?/p>
select regexp_substr('1@/231_3253/ABc','@+[[:alnum:]]*') from dual;
Output: @
@+ 表示匚w1个或者多个@
[[:alnum:]]* 表示匚w0个或者多个字母或数字字符
select regexp_substr('1@/231_3253/ABc','@+[[:alnum:]]+') from dual;
Output: Null
@+ 表示匚w1个或者多个@
[[:alnum:]]+ 表示匚w1个或者多个字母或数字字符
select regexp_substr('@1PSN/231_3253/ABc125','[[:digit:]]+$') from dual;
Output: 125
[[:digit:]]+$ 表示匚w1个或者多个数字结字符
select regexp_substr('1@/231_3253/ABc','@+[[:alnum:]]+') from dual;
Output: Null
@+ 表示匚w1个或者多个@
[[:alnum:]]+ 表示匚w1个或者多个字母或数字字符
select regexp_substr('@1PSN/231_3253/ABc125','[[:digit:]]+$') from dual;
Output: 125
[[:digit:]]+$ 表示匚w1个或者多个数字结字符
select regexp_substr('@1PSN/231_3253/ABc','[^[:digit:]]+$') from dual;
Output: /ABc
[^[:digit:]]+$ 表示匚w1个或者多个不是数字结字符
select regexp_substr('Tom_Kyte@oracle.com','[^@]+') from dual;
Output: Tom_Kyte
[^@]+ 表示匚w1个或者多个不?#8220;@”的字W?/p>
select regexp_substr('1PSN/231_3253/ABc','[[:alnum:]]*',1,2)
from dual;
Output: Null
[[:alnum:]]* 表示匚w0个或者多个字母或者数字字W?/p>
注:(x)因ؓ(f)是匹?个或者多个,所以这里第2ơ匹配的?#8220;/”Q匹配了0ơ)(j)Q而不?#8220;231”Q所以结果是“Null”
q里我们有时候会(x)查询字符串里asdfafd<main>dafda q里我们要取?lt;main>q个字符?/p>
Select regexp_substr('asdfafd<main>dafda','<[^>]+>') from dual
Output: <main>
q里我们?lt;>中间M个^>q样在匹?lt;之后Q在向后查询的时候确保在匚w?gt;之前不再在有>,不然的话p有可以出错的情况?/p>
Select regexp_substr('asdfafd<main>da>fda','<[^<]+>') from dual
Output: <main>da>
在这个例子中Q我们在<main>之后q在da>Q这L(fng)话,如果我们没有d^>Q正则表辑ּ׃(x)向后l箋d配,直到最后一?gt;Q这样就?x)出现偏?/p>
q个通常用来实现字符串的列传?/p>
select regexp_substr('123;234;345;456;567;678;789','[^;]+',1,rownum) from dual
connect by rownum <= length('123;234;345;456;567;678;789') - length(replace('123;234;345;456;567;678;789',';'))+1
q里lengthq里操作是先得到有多个“;”Q再通过 connect by rownum方式来做一行成多行的操作,在变成多行之后,可以通过regexp_substr来取字符串的操作
接着上一个例?/p>
a,b,c,d,e,d,f,a,nq样的一个字W串Q我们现在要把字W串里一些重复去掉,q样的话l果是a,b,c,d,e,f,nL了d与a的两个字W串
select wm_concat(new_row) from (
select distinct regexp_substr('a,b,c,d,e,d,f,a,n','[^,]+',1,rownum) new_row from dual
connect by rownum<=length('a,b,c,d,e,d,f,a,n')-length(replace('a,b,c,d,e,d,f,a,n',',')))
通过转成多行的,再用distinct L重复Q然后我们再通过wm_concat来字W串合ƈ来完成?/p>
再来一个ip格式转换的例子吧Q我们一般的IP的格式是12.19.168.27现在要不?位的补前面?Q结果是012.019.168.027
select wm_concat(new_value) from (
select
lpad(regexp_substr('12.19.168.27','[^.]+',1,rownum) ,3,'0') new_value,rownum
from dual
connect by rownum<5
order by rownum)
来一个验证IP是数字是否正?/p>
select count(*) from(
select
lpad(regexp_substr('12.19.168.27','[^.]+',1,rownum) ,3,'0') new_value,rownum
from dual
connect by rownum<5)
where new_value>=0 and new_value<256
having count(*) =4
来一个IP字符串格式{换成数字型IP
select sum(new_value*power(256,4-rm)) from (
select regexp_substr('12.19.168.27','[^.]+',1,rownum) new_value,rownum rm from dual
connect by rownum<=4
)
接下来介l一个regexp_instr函数
REGEXP_INSTR 函数使用正则表达式返回搜索模式的L(fng)和终炏VREGEXP_INSTR 的语法如下所C。REGEXP_INSTR q回一个整敎ͼ指出搜烦(ch)模式的开始或l束的位|,如果没有发现匚w的|则返??/p>
语法Q?/p>
2.REGEXP_INSTR与INSTR函数相同Q返回字W串位置
REGEXP_INSTR(srcstr, pattern [, position [, occurrence [, return_option [,match_option]]]])
与REGEXP_SUBSTR一P它也有变量pattern、position(开始位|?、occurrence 和match_parameterQ这里主要介l一下新参数return_option 的作用,它允许用户告诉OracleQ模式出现的时候,要返回什么内宏V?/p>
Select regexp_instr('asdfafd<main>da>fda','sd') from dual
Output:2
q里L询sd的位|,q个和instr是在相同?/p>
Select regexp_instr('asdfafd<main>da>fda','da',1,2) from dual
q里是查询daW二出现的位|?/p>
q有我们l常?x)遇CU情冉|Q查询某个字D,如果是等?#8220;上v”?#8220;北京”或者我们温州就写成大城市,其它的写成小城市Q我们一般会(x)考虑使用decodeq种方式
Select decode('上v','上v','大城?,'北京' ,'大城? ,'温州' ,'大城?,'城?) from dual
只有两个我们可能觉的sql也不是很冗长Q如果有四五个的话,有炚w了,q里使用regexp_instr可以很多的L?/p>
Select decode (regexp_instr('北京','^(上v|北京|温州)'),0,'城?, '大城?) from dual
通过regexp_instr不匹配时?的条Ӟq样可以完成了
最后一个函数regexp_replace
REGEXP_REPLACE 函数是用另外一个值来替代串中的某个倹{例如,可以用一个匹配数字来替代字母的每一ơ出现。REGEXP_REPLACE的格式如下所C?/p>
语法Q?/p>
4.REGEXP_REPLACE与REPLACE函数相同Q替换原字符串中的字W内?/p>
REGEXP_REPLACE(srcstr, pattern [,replacestr [, position [, occurrence [,match_option]]]])
q个替换函数q是一个非常好用的?/p>
如我们在有一个字W串adfadfa (main) next 现在我们要把()替换?lt;>Q这里我们可能想用replace可以搞定了Q但是我们现在做的是(之后必须?q样?)我们才替换把<>.
select regexp_replace('adfadfa (main) next ','(\()([^\)]*)(\))','<\2>') from dual
output: adfadfa <main> next
q里q是一个\做ؓ(f)转义字符?/p>
再来一个ip格式转换的例子吧Q我们一般的IP的格式是12.19.168.27现在要不?位的补前面?Q结果是012.019.168.027
select regexp_replace(
regexp_replace('12.19.168.27','([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})',
'00\1.00\2.00\3.00\4') ,
'([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}$)','\2\4\6\8')
from dual
output: 012.019.168.027
q里我分成两步来操作Qregexp_replace('12.19.168.27','([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})',
'00\1.00\2.00\3.00\4')我首先让每个字W串做添?Q这h个字W串都会(x)大于3Q再
'([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}\.)([0-9]*)([0-9]{3}$)','\2\4\6\8')
q整个字W串分成8D,q样我们只要2???q四个段可以了?/p>
下面一个例子中Q在每两个字W之间插入一个空格符
SELECT regexp_replace('YAHOO', '(.)', '\1 ') AS output FROM dual;
Output: Y A H O O
q个用一个@环的方式L作,q蛮好的?/p>
select regexp_replace(
regexp_replace('12.19.168.27','([^.]+)'
,'00\1')
,'([^.]*)([^.]{3})','\2')
from dual
接着刚才那个Q我们可以把replace循环替换的方式来操作?/p>
]]>