1

REGEXP_SUBSTRを使用して、Oracleで必要なこれらのデータを取得する方法

SPRINTMVNO_PM_CDR_IWIRELESS_20121110_0813.csv get '08'in last four digits
RK_IPDR_RKMSG2_0043722_DT_20121113162710.txt  get '0043722' in the middle(between'_')
wireless_201211120015_201211120515            get '0515' (last four digits)

何度も試しましたが、一部の式はPHPまたは他の言語では正常に機能しますが、ORACLEでは機能しません。構文が違うかもしれません。

例: /(?<=_)[0-9]*(?=_)/phpで数値を取得するために使用できる2番目のものですが、これはOracleでは機能しません。
私は試した

SELECT REGEXP_SUBSTR('RK_IPDR_RKMSG2_0043722_DT_20121113162710.txt','(?<=_)[0-9]*(?=_)') 
  FROM dual;

出力なし。したがって、2つのスラッシュラインの問題ではありません

この質問の別の定式化は、「Oracleの正規表現を使用して、文字間でコンテンツを取得する方法、または文字で開始するが、文字を含めない方法」です。

文字列関数を使用してこれらのデータを簡単に取得できることはわかっています。問題は、処理する文字列がたくさんあり、それぞれが取得するデータが異なることです。したがって、パターンをデータベースに保存し、1つのregexp_substrを使用してすべてのデータを取得したいと思います。それ以外の場合は、これらのルールをハードコーディングする必要があります。

4

3 に答える 3

1

正規表現の前後のスラッシュは、正規表現とは何の関係もありません。

それらはperl/javascript言語のアーティファクトです。

スラッシュなしで試してください

于 2012-11-17T00:20:30.257 に答える
1

オラクルは、いくつかの巧妙な操作のために組み合わせることができるいくつかの単純な文字列関数を提供しているため、オラクルの実践者は正規表現なしで何年も生き残りました。

たとえば、文字列の最後の下線の後の最初の2文字を見つけるには、次のようにSUBSTR()とINSTR()を使用します。

with t as (select 'SPRINTMVNO_PM_CDR_IWIRELESS_20121110_0813.csv' str from dual)
select substr(str, instr(str, '_', -1)+1, 2)
from t
/

INSTR()呼び出しには、後ろからカウントを開始するための負のオフセットがあることに注意してください。文字列の最後の4文字を取得するには、同じトリックを使用します。

with t as (select 'iwireless_201211120015_201211120515' str from dual)
select substr(str, -4)
from t
/

アンダースコア、数字、アンダースコアのパターンを識別する最も簡単な方法は正規表現を使用することですが、TRIM()を使用して結果からアンダースコアを削除できます。

with t as (select 'RK_IPDR_RKMSG2_0043722_DT_20121113162710.txt' str from dual)
select trim('_' from regexp_substr(str, '_([0-9]+)_'))
from t
/

これらの手法が機能することを証明する SQLフィドルを次に示します。

Oracleには膨大な数の関数があり、それらはドキュメントで説明されています。 詳細をご覧ください


「ケースを無視してください。オラクルの正規表現を使用して、文字間でコンテンツを取得する方法、または文字で開始するが、文字を含めない方法」の解決策が必要です。」

結果の最初または最後から文字を除外する方法があります。それは、検索パターンを部分式に分割することです。これは、指定した文字列に対して機能します。これは、先頭と末尾の下線を必要な数から分離できるためです。残念ながら、部分式パラメーターはREGEXP_SUBSTR()シグニチャーの最後のパラメーターであり、SQL関数は名前付きパラメーターを受け入れないため、他のすべてのパラメーターのデフォルト値を明示的に渡す必要があります。

とにかく、この呼び出しは、目的の文字列である2番目の部分式を返します0043722

with t as (select 'RK_IPDR_RKMSG2_0043722_DT_20121113162710.txt' str from dual)
select regexp_substr(str, '(_)([0-9]+)(_)', 1,1,'i',2)
from t
/

ユースケース重要です。REGEXP関数は、単純な同等の関数よりも実行速度が遅くなります。10gR2では、REGEXP_SUBSTR()はSUBSTR()よりも少なくとも1桁遅くなります。この違いは、多数の文字列を検索する場合と、その数が数百万になると機能しなくなる場合に顕著になります(開示:最近の苦痛)。

于 2012-11-17T08:42:20.940 に答える
0

OracleはPOSIXERE(拡張正規表現)を使用しますが、後方参照を追加するという注目すべき例外があります。しかし、POSIX EREは非常に限られており、必要なものはごくわずかです。次の正規表現を試してください。

/([0-9]{2}80|[0-9]80[0-9]|80[0-9]{2})$/

これにより、最後の4桁で80になります。

/0515$/

これにより、最後の4桁として0515が取得されます。

今、私はOracleを使ったことがないので、区切り文字が必要かどうかはわかりませんが、これら2つは機能します。真ん中のものは少しトリッキーです。「はい、そこにあります」と一緒に暮らすことができれば、

/_0043722_/

しかし、それを抽出する必要がある場合は、何をトリミングするかを指定できるいくつかのトリミング関数を見つけることができるはずです。Oracleの正規表現ではそれを行うことはできません。

ああ、そしてこれら3つすべてを1つの正規表現に組み合わせる必要がある場合:

/([0-9]{2}80|[0-9]80[0-9]|80[0-9]{2}|0515)$|_0043722_/

また、将来正規表現のリファレンスが必要な場合は、このサイトを試してください。

于 2012-11-17T01:59:39.847 に答える