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

10-264 正規表現のリキャプチャ

SQLパズル

RegexTable
ID  STR
--  ---------------------
 1  abc_de_XXX_fg
 2  abcd_e_XXX
 3  a_b_XXX_c_d
 4  a_b_cde
 5  XXX_a_b_c
 6  abcdef_XXX_ghij_klm_n

_を区切りとして、XXXの前の文字列を求める。

出力結果
ID  STR                    NEWSTR
--  ---------------------  --------
 1  abc_de_XXX_fg          de
 2  abcd_e_XXX             e
 3  a_b_XXX_c_d            b
 4  a_b_cde                null
 5  XXX_a_b_c              null
 6  abcdef_XXX_ghij_klm_n  abcdef

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


データ作成スクリプト

create table RegexTable(ID,str) as
select 1,'abc_de_XXX_fg'         from dual union
select 2,'abcd_e_XXX'            from dual union
select 3,'a_b_XXX_c_d'           from dual union
select 4,'a_b_cde'               from dual union
select 5,'XXX_a_b_c'             from dual union
select 6,'abcdef_XXX_ghij_klm_n' from dual;


SQL

col newstr for a30

--■■■リキャプチャを使う方法1■■■
select ID,str,
RegExp_Replace(str,'^(([^_]+)_)+XXX.*$|^.*$','\2') as newstr
  from RegexTable;

--■■■リキャプチャを使う方法2■■■
select ID,str,
case when instr(str,'_XXX') != 0
     then RegExp_Replace(str,'^(([^_]+)_)+XXX.*$','\2')
end as newstr
  from RegexTable;

--■■■選択の優先順位を利用する方法■■■
select ID,str,
RegExp_Replace(str, '([^_]+)_XXX|.', '\1') as newstr
  from RegexTable;


解説

選択の優先順位を利用する方法では、
Oracleの正規表現では、選択が左優先であることを使ってます。

10-267 RegExp_Replace関数で区切りデータより抽出

US-OTN --- Hahaha today I say it twice
CD氏スペシャルの使用例