0

如果关键字是“Find”,是否可以提取“Find”之间的字符串?

stackoverflow is awesome. FindHello, World!Find It has everything!

结果应该是“你好,世界!” 因为字符串在“Find”之间 我最初的想法是使用 Instr 定位两个“Find”,然后定位“Find”之间的内容。

有没有更好的方法来做到这一点?

4

2 回答 2

2

您可以使用正则表达式instr()实现您所追求的。

如果您使用的是 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来演示。

于 2012-09-10T20:12:18.640 回答
1

此查询假设处理两个以上的“查找”

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
于 2012-09-10T20:08:02.407 回答