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

10-202 正規表現の肯定先読みを代用

SQLパズル

StrTable
Val
--------------------
1234567
23499/2/3/4
Fa234st/2/3/4
Fa234st10999/2/3/4
abcdefg

Valの最初のスラッシュの前の数字の文字列を取得する。

出力結果
before              after
------------------  -------
1234567             1234567
23499/2/3/4         23499
Fa234st/2/3/4       2
Fa234st10999/2/3/4  10999
abcdefg             abcdefg

こちらを参考にさせていただきました(英語)


データ作成スクリプト

create table StrTable(Val) as
select '1234567' from dual union
select '23499/2/3/4' from dual union
select 'Fa234st/2/3/4' from dual union
select 'Fa234st10999/2/3/4' from dual union
select 'abcdefg' from dual;


SQL

--■■■ストアドファンクションを使う方法■■■
create or replace function
getStr(hikiVal varchar2) return varchar2 is
    seqFlag boolean := false;
    willOut varchar2(4000);
begin
    for i in 1..length(hikiVal) Loop
        if Ltrim(substr(hikiVal,i,1),'0123456789') is null then
            seqFlag := true;
            willOut := willOut || substr(hikiVal,i,1);
        elsif seqFlag and substr(hikiVal,i,1) = '/' then
            return willOut;
        else
            seqFlag := false;
            willOut := null;
        end if;
    end Loop;
    return hikiVal;
end;
/

col after for a10

select Val as before,
getStr(Val) as after
from StrTable;

--■■■最小マッチ(ものぐさマッチ)を使わない方法(10g以降)■■■
select Val as before,
nvl(Rtrim(RegExp_Substr(Val,'[0-9]+/'),'/'),Val) as after
from StrTable;

--■■■最小マッチ(ものぐさマッチ)を使う方法(10gR2以降)■■■
select Val as before,
RegExp_Replace(s,'^.*?([0-9]+)/.*$','\1') as after
from StrTable;


解説

10gR2からは、最小マッチ(ものぐさマッチ)を使うことができるのです。