2012-09-10 77 views
0

如果關鍵字是「查找」,是否可以提取位於「查找」之間的字符串?sql在特定單詞之間搜索字符串

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

結果應該是'你好,世界!'因爲字符串在「查找」之間 我最初的想法是使用Instr來定位兩個「查找」,然後找到「查找」之間的內容。

有沒有更好的方法來做到這一點?

+1

你的想法很好。使用instr()來解決這個問題。 –

+0

如果查找字符串中存在4次,你將如何處理這種情況? –

+0

「查找」僅僅是一個例子。實際的關鍵詞將是獨一無二的,只會發生兩次。 – sayhaha

回答

2

您可以使用regular expressionsinstr()實現你以後。

我其實更喜歡正則表達式,如果您使用的是版本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 

這得到字符串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之間返回。

這裏有一點SQL Fiddle來演示。

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