sql >> データベース >  >> RDS >> Oracle

文字列から特定の単語を削除する

    lookbehind /lookahead がサポートされていないため および単語の境界(\b ) Oracleの正規表現の実装では、単一の REGEXP_REPLACE 電話。特にケースの場合、EgorSkriptunoffが指摘 :パターンが一致し、some some some some ...のように、間に区切り文字が1つしかないものが1つずつ続きます。 。

    この場合がないと、このようなすべての文字列をこの呼び出しと一致させることができます:

    regexp_replace(
      source_string,                                       -- source string
      '([^[:alnum:]]|^)((\d)*some(\d)*)([^[:alnum:]]|$)',  -- pattern
      '\1\5',                                              -- leave separators in place
      1,                                                   -- start from beginning
      0,                                                   -- replace all occurences
      'im'                                                 -- case-insensitive and multiline 
    );
    

    パターンパーツ:

    (                -- start of Group #1
      [^[:alnum:]]   -- any non-alphanumeric character 
      |              -- or 
      ^              -- start of string or start of line 
    )                -- end of Group #1
    (                -- start of Group #2
      (              -- start of Group #3 
        \d           -- any digit
      )              -- end of Group #3
      *              -- include in previous group zero or more consecutive digits
      some           -- core string to match
      (              -- start of group #4
        \d           -- any digit
      )              -- end of group #4  
      *              -- include in previous group zero or more consecutive digits
    )                -- end of Group #2
    (                -- start of Group #5
      [^[:alnum:]]   -- any non-alphanumeric character 
      |              -- or
      $              -- end of string or end of line
    )                -- end of Group #5
    

    一致パターンに含まれる一致に使用されるセパレーター(グループ#1およびグループ#5)は、一致が成功するとソース文字列から削除されるため、3番目のregexp_replaceで指定してこの部分を復元する必要があります。 パラメータ。

    このソリューションに基づいて、ループ内で繰り返し発生するすべてのイベントを置き換えることができます。

    たとえば、次のような関数を定義できます。

    create or replace function delete_str_with_digits(
      pSourceString in varchar2, 
      pReplacePart  in varchar2  -- base string (like 'some' in question)
    )
      return varchar2
    is
      C_PATTERN_START constant varchar2(100) := '([^[:alnum:]]|^)((\d)*';
      C_PATTERN_END   constant varchar2(100) := '(\d)*)([^[:alnum:]]|$)';
    
      vPattern         varchar2(4000);
      vCurValue        varchar2(4000);
      vPatternPosition binary_integer;
    begin
    
      vPattern := C_PATTERN_START || pReplacePart || C_PATTERN_END;
      vCurValue := pSourceString;
    
      vPatternPosition := regexp_instr(vCurValue, vPattern);
    
      while(vPatternPosition > 0) loop
        vCurValue := regexp_replace(vCurValue, vPattern,'\1\5',1,0,'im');
        vPatternPosition := regexp_instr(vCurValue, vPattern);
      end loop;
    
      return vCurValue;  
    
    end;
    

    SQLまたはその他のPL/SQLコードで使用します:

    SELECT 
      delete_str_with_digits(
        'some text, -> awesome <- 123 someone, 3some3
         line of 7 :> some some some some some some some <
    222some  another some1? some22 text 0some000', 
        'some'
      )  as result_string
    FROM 
      dual
    

    SQLFiddleの例



    1. MySQLとMongoDB1000の読み取り

    2. Postgresで無効なオブジェクトを識別して削除するために利用できるオプションは何ですか(例:破損したインデックス)

    3. 大きな(または少なくとも重要な)BLOBをJDBCを使用してOracleに配置するにはどうすればよいですか?

    4. 別のテーブルからの行の参照(PostgreSQL)