トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
10-243 場合分けを使う正規表現
SQLパズル
strTable
Val
-----------------
a,b,c<x,y,z>
a,b,c
,,,,a
a,,b,,c,,d
<a,b,c,d>eee<f,g>
<と>で囲まれてないカンマを削除する。
出力結果
Val NewVal
----------------- -----------------
a,b,c<x,y,z> abc<x,y,z>
a,b,c abc
,,,,a a
a,,b,,c,,d abcd
<a,b,c,d>eee<f,g> <a,b,c,d>eee<f,g>
データ作成スクリプト
create table strTable(val) as
select 'a,b,c<x,y,z>' from dual union all
select 'a,b,c' from dual union all
select ',,,,a' from dual union all
select 'a,,b,,c,,d' from dual union all
select '<a,b,c,d>eee<f,g>' from dual;
SQL
col Val for a20
col NewVal for a20
--■■■正規表現を使う方法(10g以降)■■■
select Val,
RegExp_Replace(Val,'(<[^>]*>)|,','\1') as NewVal
from strTable;
--■■■PL/SQLを使う方法■■■
declare
KakkoFlag boolean := false;
willOut varchar2(4000);
begin
for rec in (select Val from strTable) Loop
for i in 1..length(rec.Val) Loop
if substr(rec.Val,i,1) = '<' then
KakkoFlag := true;
willOut := willOut || substr(rec.Val,i,1);
elsif substr(rec.Val,i,1) = '>' then
KakkoFlag := false;
willOut := willOut || substr(rec.Val,i,1);
elsif substr(rec.Val,i,1) = ',' and KakkoFlag then
null;
else
willOut := willOut || substr(rec.Val,i,1);
end if;
end Loop;
DBMS_Output.Put_Line(RPad(rec.Val,20) || '■' || willOut);
willOut := null;
end Loop;
end;
/
解説
正規表現の評価の仕組みを理解した上で
<と,の2通りで、場合分けをしてます。
先読みが使えない、Oracleの正規表現でもなんとかなる時もあるのです。