3

このような文字列/列があります

String a = "000003023_AggregateStopLossLimit_W x3A 973911_2012-12-22.PDF";

その部分を含まない部分文字列を作成したい' x3A 973911'

つまり、私はこのようなものが欲しいということです。

000003023_AggregateStopLossLimit_W_2012-12-22.PDF

異なる値を持つ文字列のリストがありますが、形式は同じです。最初のスペースの後に来て次の「_」で終わる文字列の部分を削除したい。

これは私がすでに行ったことです。これは正常に機能していますが、より良い方法があるかどうかを知りたいです。

String b = a.replaceAll(a.substring(a.indexOf(" "), a.indexOf("_",a.indexOf(" "))),"");

Javaではなく、オラクルであるdb自体でこれを行うことができれば、さらに良いでしょう。select を使用して、このフォーマットされた文字列を列から直接取得するアイデアはありますか?

もう 1 つの要件として、ファイルの拡張子を表示したくありません。
したがって、「。」の後には何もありません。これは、このようなことを意味'000003023_AggregateStopLossLimit_W_2012-12-22'
します APCの以前のソリューションを使用して、次のことを試しました

 select regexp_replace ( your_string
                          , '([^[:space]]*) (.*)_(.*)....'
                          , '\1_\3') as new_string from your_table

これは今のところうまくいっています。
これは最後の 4 文字を削除する必要があり、拡張子が 3 より多いまたは少ない場合、または文字列が切り捨てられていない場合、適切な結果が得られないリスクがあります。
私はそれを行うためのより審美的な方法を探しています。
チャンスはありますか?

4

7 に答える 7

4
final String r = a.replaceAll(" .*?(?=_)", "");

rを印刷すると、次の出力が得られます。

000003023_AggregateStopLossLimit_W_2012-12-22.PDF
于 2012-12-31T10:13:36.537 に答える
3

データベースでそれを行うには:

select regexp_replace ( your_string
                         , '([^[:space]]*) (.*)_(.*)'
                         , '\1_\3') as new_string
from your_table

残念ながら、Oracle には、正規表現の実装で遅延性 (非貪欲性) を強制するための構文がありません。そのため、元の '(.*) ' にはx3A: が含まれており、最後のスペースとそれに続くアンダースコアが一致しました。ただし、否定構文は、文字列を最初のスペースまで分離します。

「Wの後の「_」が抜けています。それも手に入れるチャンスはありますか?」

任意の方法で置換文字列をフォーマットできます。簡単な方法は、私が行ったことを実行し、一致した 2 つのパターンの間にアンダースコアをハードコーディングすることです。または、それ自体を検索パターンにして、置換文字列に含めることもできます (ただし、より複雑な検索では、これを行う可能性が高くなります)。


Oracle は 10g で正規表現を導入しました。関数はドキュメントで説明されています。正規表現の実装は POSIX に準拠しているため、たとえば Perl で遭遇する可能性のある機能の一部が欠けています。正規表現のサポートについては、SQL ref の付録で詳しく説明されています。

チュートリアルに関しては、まあ、私は O'Reilly ポケット ブックのコピーを高く評価しています。私は Open World 2003 で自分のコピーをもらいましたが、電子ブックの価格は手ごろです。 ここで購入します。もう 1 つの良い出発点はcd、OTN フォーラムの一連のスレッドです。ここから読み始めてください

于 2012-12-31T11:02:11.843 に答える
2

SQL ソリューションが必要な場合、これにより行が更新されます。

update yourtable
set field = substr(field, 0, instr(field, ' ')-1) || substr(field, instr(field, '_', instr(field, ' ')))
;

これは変換された値を表示するだけです:

select
  yourtable.field,
  case
    when instr(field, '_', instr(field, ' '))>instr(field, ' ')
    then substr(field, 0, instr(field, ' ')-1) || substr(field, instr(field, '_', instr(field, ' ')))
    else field
  end as new_field
from
  yourtable
于 2012-12-31T11:01:32.773 に答える
1

REGEX_REPLACE 関数を置き換える必要があります。

http://docs.oracle.com/cd/B12037_01/server.101/b10759/functions115.htm#SQLRF06302

于 2012-12-31T10:21:15.540 に答える
1

あなたが提供したコードの正規表現の問題とは別に、読みにくいこともわかりました。

以下を試してください:

int f = a.indexOf(" ");
int l = a.lastIndexOf("_");
a = a.substring(0,f+1) + a.substring(l+1, a.length);
于 2012-12-31T10:09:40.523 に答える
1

replaceAll引数として正規表現を取ります。部分文字列に正規表現マーカー (たとえば[、など+) が含まれていると、予期しない動作が発生します。

replace同じことを行いますが、パラメーターとして文字列を取る代わりに使用できます。

それとは別に、_区切り文字としてスペースと a があり、かつその間の部分文字列が他の場所で発生しないことがわかっている場合、アプローチは問題ないように見えます。中間変数を使用して、もう少し読みやすくすることができます。

int start = a.indexOf(" ");
int end = a.indexOf("_", start);
String b = a.substring(0, start) + a.substring(end, a.length());
于 2012-12-31T10:06:47.907 に答える