トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

2-1-12 指定文字列の前後の文字列

SQLパズル

BeforeAfterTable
Val
----------
abc9999
111abc9999
111abc
(・∀・)

文字列から、'abc'の前後の文字列を取得する
ただし、文字列に'abc'が存在しない場合は、文字列をそのまま取得する。

出力結果
Val         abcの前の文字列  abcの後の文字列
----------  ---------------  ---------------
abc9999     null             9999
111abc9999  111              9999
111abc      111              null
(・∀・)    (・∀・)         (・∀・)


データ作成スクリプト

create table BeforeAfterTable(Val) as
select 'abc9999'    from dual union
select '111abc9999' from dual union
select '111abc'     from dual union
select '(・∀・)'   from dual;


SQL

--■■■substr関数を使う方法■■■
select Val,
substr(Val,1,decode(instr(Val,'abc'),0,Length(Val),instr(Val,'abc')-1)) as "abcの前の文字列",
substr(Val,decode(instr(Val,'abc'),0,1,instr(Val,'abc') + Length('abc'))) as "abcの後の文字列"
from BeforeAfterTable
order by Val desc;

--■■■正規表現を使う方法(10g以降)■■■
col "abcの前の文字列" for a18
col "abcの後の文字列" for a18

select Val,
RegExp_Replace(Val,'^(.*)abc.*$','\1') as "abcの前の文字列",
RegExp_Replace(Val,'^.*abc(.*)$','\1') as "abcの後の文字列"
from BeforeAfterTable
order by Val desc;


解説

Oracle11gの正規表現ですら、肯定先読み、肯定戻り読みをサポートしていないので、
RegExp_Substr関数ではなく、RegExp_Replace関数と後方参照を使う必要があるようです。