码迷,mamicode.com
首页 > 数据库 > 详细

SQL语句——18、正则表达式函数

时间:2020-01-05 10:07:41      阅读:89      评论:0      收藏:0      [点我收藏+]

标签:范围   nec   app   控制   smi   标记   匹配   递归   指定   

Oracle正则表达式(regularexpression)

元字符 字符含义 举例说明
^ 匹配字符串的开始位置(在[]中使用,此时它表示不接受该字符集合。
^a:匹配以a开始的字符串
[^a]:匹配不含a的字符串
-
当使用在a-m表示范围;
当使用在第一个字符时表示
连字符串,如[-abc]
 
$ 匹配字符结束位置 ‘a$‘:匹配以a结束的字符串
. 匹配除换行符 n之外的任何单字符。  
? 匹配前面的子表达式零次或一次 tr(y(ing)?):可以表示try或者trying
* 匹配前面的子表达式零次或多次  
+ 匹配前面的子表达式一次或多次  
() 标记一个子表达式的开始和结束位置
a(b)*可以匹配
ab,abb,abbb,youabb
(c|d)匹配c或d
[] 标记一个中括号表达式
[cd]匹配选择c或d等同于
(c|d)。匹配的是单字符,[^cd]是匹配c,d之外的单字符。
[a-z]表示所有小写字母
{m,n} m= <出现次数 <=n,‘{m}‘表示出现m次,‘{m,}‘表示至少出现m次。  
| 表示或者的关系。指明两项之间的一个选择  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

字符簇 字符含义
[[:alpha:]] 任何字母
[[:digit:]] 任何数字
[[:alnum:]] 任何字母和数
[[:space:]] 任何空白字符
[[:upper:]] 任何大写字母
[[:lower:]] 任何小写字母
[[:punct:]] 任何标点符号
[[:xdigit:]] 任何16进制的数字,相当于[0-9a-fA-F]

 

 

 

 

 

 

 

 

regexp_like(‘S‘,‘RE‘,‘O‘)

  • S 被搜索的字符串或者列表达式
  • RE 正则内容
  • O 参数(可选)
idle> select ename from emp where regexp_like(ename,S);

ENAME
----------
SMITH
JONES
SCOTT
ADAMS
JAMES

idle> select ename from emp where regexp_like(ename,^S.*T);

ENAME
----------
SMITH
SCOTT

idle>

idle> idle> select ename from emp where regexp_like(ename,^s.*T$,i);忽略大小写

ENAME
----------
SCOTT

 

regexp_replace(S,‘RE‘,‘NEW‘)

idle> select ename,regexp_replace(ename,S..T,=) aaa from emp where regexp_like (ename,S..T);

ENAME   AAA
---------- ----------
SMITH   =H
SCOTT   =T

复杂用法

SELECT REGEXP_REPLACE(
Ellen Hildi Smith,
(.*) (.*) (.*), \3, \1 \2)
FROM dual

REGEXP_REPLACE(EL
------------------
Smith, Ellen Hildi 

该 SQL 语句显示了用圆括号括住的三个单独的子表达式。每一个单独的子表达式包含一个匹配元字符 (.),并紧跟着 * 元字符,表示任何字符(除换行符之外)都必须匹配零次或更多次。空格将各个子表达式分开,空格也必须匹配。圆括号创建获取值的子表达式,并且可以用 \digit 来引用。第一个子表达式被赋值为 \1 ,第二个 \2,以此类推。这些后向引用被用在这个函数的最后一个参数 (\3, \1 \2) 中,这个函数有效地返回了替换子字符串,并按期望的格式来排列它们(包括逗号和空格)。表 11 详细说明了该正则表达式的各个组成部分。 

REGEXP_COUNT

在Oracle的11g版本中引入,使用该函数可以统计字符串出现的次数。

REGEXP_COUNT (source_char, pattern [, position [, match_param]])

source_char:需要进行正则处理的字符串

pattern:进行匹配的正则表达式

position:起始位置,从第几个字符开始正则表达式匹配(默认为1)

match_param:模式(‘i’ 用于不区分大小写的匹配

                  ‘c’ 用于区分大小写的匹配

                  ‘n’ 允许句点(.)作为通配符去匹配换行符。如果省略该参数,则句点将不匹配换行符

                  ‘m’ 将源串视为多行。即Oracle 将^和$分别看作源串中任意位置任何行的开始和结束,而不是仅仅看作整个源串的开始或结束。如果省略该参数,则Oracle将源串看作一行。

                  ‘x’ 忽略空格字符。默认情况下,空格字符与自身相匹配。

                  如果为match_param 指定了多个相互矛盾的值,那么Oracle 使用最后一个值。

 

                 )

REGEXP_SUBSTR

function REGEXP_SUBSTR(String, pattern, position, occurrence, modifier)

  • String:需要进行正则处理的字符串
  • pattern:进行匹配的正则表达式
  • position:起始位置,从第几个字符开始正则表达式匹配(默认为1)
  • occurrence:标识第几个匹配组,默认为1modifier:模式(‘i‘不区分大小写进行检索,‘c‘区分大小写进行检索,默认为‘c‘)

例1:查询使用正则分割后的第一个值,也就是17

SELECT REGEXP_SUBSTR(17,20,23,[^,]+,1,1,i) AS STR FROM DUAL;  

STR
-----
17

 

例2:查询使用正则分割后的最后一个值,也就是23

SELECT REGEXP_SUBSTR(17,20,23,[^,]+,1,3,i) AS STR FROM DUAL;  

STR
----
23

例3:将字符串拆成行

select regexp_substr(17,20,23,[^,]+,1,level)  AS STR
  from dual
connect
by level<=regexp_count(17,20,23,,)+1 STR ---- 17 20 23

例4:当表(多行数据)作为数据源时,将表中的某字段转换为行,将会出现笛卡尔乘积。

SELECT lpad(~,(LEVEL-1)*5,~)||CKJYM1 CKJYM1,LEVEL,regexp_substr(CKJYM1,[^,]+,1,level) CKJYM
              FROM (SELECT B10,B04 CKJYM1
                      FROM dual
                      union all
                     SELECT B11,B12 CKJYM1
                      FROM dual ) T
            CONNECT BY LEVEL <= REGEXP_COUNT(CKJYM1,B)  

 CKJYM1                      LEVEL         CKJYM
---------------------   -------------   ----------
B10,B04                       1              B10
~~~~~B10,B04                  2              B04
~~~~~B11,B12                  2              B12
B11,B12                       1              B11
~~~~~B10,B04                  2              B04
~~~~~B11,B12                  2              B12

CONNECT BY相当于是一个递归的自连接,不断地把每层的连接结果叠加到结果集中。两层之间的连接条件和递归出口写在CONNECT BY中。

在这里数据并无父子关系,只是要让同一行数据重复出现。因此我们的连接的条件只用到了表的主键CKJYM1=PRIOR CKJYM1, 此外再用LEVEL控制层数作为递归出口,就可以获得想要的数据。但ORACLE有个检查,如果你有前后连接条件(CKJYM1=PRIOR CKJYM1),当同一行数据再次出现,它就会报一个错:ORA-01436: CONNECT BY loop in user data

为了欺骗它,这里用了一个PRIOR DBMS_RANDOM.VALUE(相当于获取随机数), 因为DBMS_RANDOM.VALUE每次调用都返回不同结果,所以它认为两行数据不一样,所以不报错了。

所以sql应改为:

SELECT lpad(~,(LEVEL-1)*5,~)||CKJYM1 CKJYM1,LEVEL,regexp_substr(CKJYM1,[^,]+,1,level) CKJYM
              FROM (SELECT B10,B04 CKJYM1
                      FROM dual
                      union all
                     SELECT B11,B12 CKJYM1
                      FROM dual ) T
            CONNECT BY LEVEL <=
                       REGEXP_COUNT(CKJYM1,B)  
                       and CKJYM1=PRIOR CKJYM1
                       and prior dbms_random.value is not null

CKJYM1 LEVEL CKJYM
------------ -------- ---------- B10,B04 1 B10 ~~~~~B10,B04 2 B04 B11,B12 1 B11 ~~~~~B11,B12 2 B12

SQL语句——18、正则表达式函数

标签:范围   nec   app   控制   smi   标记   匹配   递归   指定   

原文地址:https://www.cnblogs.com/marxist/p/12151189.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!