1

バックリファレンス値を使用して置換文字列が動的に選択されることを除いて、バニラの regexp_replace を実行しようとしています。

もう少し状況を説明するために、2 つの文字列を (簡単にするために、同じテーブルの 2 つの列で言うと) 持っています。最初のものには、文字列リテラル自体の一部として {1}、{2} などのプレースホルダーが含まれています。これは、2 番目の文字列の対応するサブフィールドに置き換える必要があります (「|」などの定数区切り文字でトークン化した後)。

したがって、次の場合:

Str1 = '素早い茶色の {1} が怠惰な {2} を飛び越える。'

Str2 = 'キツネ|犬'

私たちは結果を必要としています.

理想的な世界では、Oracle (11g Enterprise 64 ビット) でこれが可能になります。


with x as (select 'The quick brown {1} jumps over the lazy {2}.' col1, 'fox|dog' col2 from dual)
select regexp_replace(x.col1, '({[0-9]+})', regexp_substr(x.col2,'[^|]+',1,'\1')) as result
from x

ただし、2 番目の regexp_substr は、外側の regexp_replace 呼び出しからの後方参照を認識せず、ORA-17222: 無効な数値をスローします。

私のビジネスケースは、このデータを含む (おそらく実体化された) ビューを作成することであるため、ストアドプロシージャまたは関数を作成したくありません。これを行うことができるワンライナーがあればいいのにと思います。

さまざまなフォーラムを見ると、Oracleはこの後方参照の受け渡しをサポートしていない可能性があるため、質問のタイトルは少し誤解を招く可能性があります. 私はプログラミングの経験はありますが、Oracle自体は経験していないので、優しくしてください!

一部のブラウジングでは、複雑な正規表現パズルに MODEL 句や xmltables (今日まで聞いたことがない) などのあいまいなものを使用する傾向があることが示されていますが、見落としているぎこちないほど単純なものがあると思います。

4

2 に答える 2

2

私は単純な PL/SQL 関数を使用します。これは、プレースホルダーを反復処理して変数を置換するための 1 つのループです。また、SQL 内で使用してビューを定義することもできます。

純粋な SQL ソリューションが本当に必要な場合は、一般的なテーブル式を使用したものを次に示します (これは決してぎこちなく単純ではありません)。

with data as (
  select 1 id, 'The quick brown {1} jumps over the lazy {2} and {3}.' txt, 'fox|dog|cat' || '|' vars from dual
  union all
  select 2 id, 'Hello {1}' txt, 'world' || '|' vars from dual
),

recursive (id, txt, vars, i) as (
  select id, txt, vars, 1 i
  from data
  union all
  select id,
         replace (txt,
                  '{' || i || '}',
                  regexp_substr(vars, '[^|]+')),
         substr(vars, instr(vars, '|') + 1),
         i+1
  from recursive
  where instr(vars, '|') > 0)

select txt
from (select txt, row_number() over (partition by id order by i desc) rn
      from recursive)
where rn = 1;
于 2013-10-22T21:31:09.447 に答える
0

実際、これを試してみてください(私の以前の回答はキャプチャするのを忘れていましたregexp_substr):

with x as (select 'The quick brown {1} jumps over the lazy {2}.' col1, 'fox|dog' col2 from dual) select regexp_replace(x.col1, '({[0-9]+})', regexp_substr(x.col2,'([^|]+)',1,1,'i',1)) as result from x;
于 2014-03-14T16:02:27.300 に答える