题目写的有点绕,实际的意思是,如何在一个给定的字符串中,识别出有连续的如英文字符或数字,且这些英文字符或数字也是连续的(2个或2个以上)。
即,如12、123、abc、abcd这样的情况。
一开始遇到这个问题,我的思路是以类似连续号段的这种处理方式来解决,但是两者的不同之处在于,一个是字符串本身的判断,一个是字符串与字符串之间的判断。两者是不同的。
那思路又转为,可以将字符串本身拆成多行,然后判断这些行之间的连续性。这样处理未尝不可,曾经也干过这事,不过有个缺点就是,中间结果集会以几倍的方式增长,处理的性能也会降低。
于是,就考虑是否可以在字符串内部解决。后面的解决的办法告诉我,如果还是用老的方法去套,你是会绕进去的,最终也找不到解决办法。于是我换了个角度,考虑到连续的字符串,其实其组合是有限的,所以可以将这些字符串拼接出来,然后再到原始字符串去查找即可。那连续的字符串如何生成呢?
代码如下:
-
select replace(sys_connect_by_path(c, \',\'), \',\') ss
-
from (select rownum i, chr(65 + rownum - 1) c
-
from dual
-
connect by rownum <= 26)
-
connect by prior i = i - 1
以上实现字符串的所有顺序组合情况。
下面实现对连续字符串的筛选(2个及以上):
-
select ss
-
from (select replace(sys_connect_by_path(c, \',\'), \',\') ss
-
from (select rownum i, chr(65 + rownum - 1) c
-
from dual
-
connect by rownum <= 26)
-
connect by prior i = i - 1)
-
where length(ss) >= 2
然后,使用正则表达式取出其中连续的英文字符:
-
select teststr,
-
regexp_substr(upper(teststr), \'[A-Z]{2,10}\') reqstr
-
from test
-
where regexp_substr(upper(teststr), \'[A-Z]{2,10}\') in
-
(select ss
-
from (select replace(sys_connect_by_path(c, \',\'), \',\') ss
-
from (select rownum i, chr(65 + rownum - 1) c
-
from dual
-
connect by rownum <= 26)
-
connect by prior i = i - 1)
-
where length(ss) >= 2)
完成。
如果是数字,那么应用的情况可能会有两种:
第一种是从类似手机号码这样的字符串中找出存在连续数字的(这种是从纯数字中取)。
第二种是从字符串中,找出存在连续数字的(这种字符串是多种字符的组合,除数字外也可能含有英文及中文字符等,只是要取其中连续部分的数字来判断)
第二种比较简单,跟前面介绍的方法类似。第一种的话,可能不仅连续数字需要查,而且还有相同数字的需求,所以,可以这样实现:
-
with
-
tmp1 as(select rownum - 1 r from dual connect by rownum <= 10),
-
tmp2 as(select lpad(a.r, b.r, a.r) rr from tmp1 a, tmp1 b),
-
tmp3 as(
-
select rr from tmp2 where length(rr)>4
-
union all
-
select ss from (
-
select replace(sys_connect_by_path(n, \',\'), \',\') ss
-
from (select rownum i, to_char(rownum-1) n
-
from dual
-
connect by rownum <= 10)
-
connect by prior i = i - 1)
-
where length(ss) >= 4)
-
select c_mobileno from taccoinfo a, tmp3 b where instr(a.c_mobileno, b.rr) > 0
其作用是,找出存在至少四个数字是连续的,或相同的数字型的字符串。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29734436/viewspace-1262023/
,如需转载,请注明出处,否则将追究法律责任。