如果关键字是“Find”,是否可以提取“Find”之间的字符串?
stackoverflow is awesome. FindHello, World!Find It has everything!
结果应该是“你好,世界!” 因为字符串在“Find”之间 我最初的想法是使用 Instr 定位两个“Find”,然后定位“Find”之间的内容。
有没有更好的方法来做到这一点?
如果您使用的是 10g 或更高版本,我实际上更喜欢正则表达式,因为我发现做多次扭曲instr()
相当笨拙,但这取决于您。
with phrases as (
select 'stackoverflow is awesome. FindHello, World!Find It has everything!' as phrase
from dual
)
select substr( phrase
, instr(phrase,'Find',1,1) + 4
, instr(phrase,'Find',1,2)
- instr(phrase,'Find',1,1)
- 4
)
from phrases
这将获取 string 的第一次和第二次出现Find
,从第一个字符开始,然后使用这些来计算您应该在其上执行子字符串的位置。
或者,使用正则表达式:
with phrases as (
select 'stackoverflow is awesome. FindHello, World!Find It has everything!' as phrase
from dual
)
select regexp_replace(phrase
, '([[:print:]]+Find)([[:print:]]+)(Find[[:print:]]+)', '\2')
from phrases
;
这需要多次打印任何可打印字符,然后是字符串Find
等。但是,主要是分组()
,它将短语的每个部分分开。这\2
意味着原始匹配的字符串只返回第二组,即Find
返回 's 之间的字符串。
这是一个小SQL Fiddle来演示。
此查询假设处理两个以上的“查找”
with SourceString as(
select 'Find123Find45345Find76876234Find87687Find' s_string
, 'Find' delimiter
from dual
)
select substr(s_string, f_f - s_f + length(delimiter), s_f-Length(delimiter ) )
from (select f_f
, s_f
from(select f_f
, f_f - lag(f_f, 1, f_f) over(order by 1) s_f
from (select Instr(s_string, delimiter , 1, level) f_f
from SourceString
connect by level <= Length(s_string))
)
where s_f > 0)
, SourceString