sql >> Databáze >  >> RDS >> Oracle

odstranit konkrétní slovo z řetězce

Kvůli nedostatku podpory pro lookbehind/lookahead a hranice slova (\b ) v implementaci regulárního výrazu Oracle se zdá být nemožné splnit všechny požadavky v jediném REGEXP_REPLACE volání. Zejména pro případ, upozornil Egor Skriptunoff :shody vzorů, následované jeden po druhém s pouze jedním oddělovačem mezi nimi jako some some some some ... .

Bez tohoto případu je možné porovnat všechny tyto řetězce s tímto voláním:

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 
);

Části vzoru:

(                -- 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

Protože oddělovače používané pro shodu (skupina č. 1 a skupina č. 5) obsažené ve vzoru shody, budou při úspěšné shodě odstraněny ze zdrojového řetězce, takže musíme tyto části obnovit zadáním ve třetím regexp_replace parametr.

Na základě tohoto řešení je možné nahradit všechny, dokonce i opakující se výskyty v rámci smyčky.

Můžete například definovat funkci jako:

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;

a použijte jej s SQL nebo jiným PL/SQL kódem:

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

Příklad SQLFiddle



  1. Známky toho, že vaše databáze již pro vás nefunguje

  2. PHP - Pole jednoduchého vnořeného neuspořádaného seznamu (UL).

  3. Připojení PHP na Linuxu k Microsoft Access na Windows Share

  4. Automaticky zvýšit varchar v dotazu SQL