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 dualconnect 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
原文地址:https://www.cnblogs.com/marxist/p/12151189.html