Oracle
 sql >> Baza danych >  >> RDS >> Oracle

usuń określone słowo z ciągu

Z powodu braku wsparcia dla lookbehind/lookahead i granica słów (\b ) w implementacji wyrażeń regularnych Oracle wydaje się niemożliwe spełnienie wszystkich wymagań w jednym REGEXP_REPLACE połączenie. Zwłaszcza w przypadku wskazanego przez Egora Skriptunoffa :dopasowanie wzorca, po którym następuje jeden po drugim z tylko jednym separatorem między nimi, jak some some some some ... .

Bez tego przypadku możliwe jest dopasowanie wszystkich takich ciągów za pomocą tego wywołania:

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

Części wzoru:

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

Ponieważ separatory używane do dopasowania (Grupa #1 i Grupa #5) zawarte we wzorcu dopasowania zostaną usunięte z ciągu źródłowego po pomyślnym dopasowaniu, więc musimy przywrócić te części, określając w trzecim regexp_replace parametr.

W oparciu o to rozwiązanie możliwe jest zastąpienie wszystkich, nawet powtarzających się wystąpień w pętli.

Na przykład możesz zdefiniować taką funkcję:

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;

i używaj go z SQL lub innym kodem 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

Przykład SQLFiddle



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wykonywanie zapytań Dynamic Sql w Oracle

  2. Jak wywołać REPLACE z CLOB (bez przekraczania 32K)

  3. Jak usunąć wszystkie tabele użytkowników?

  4. Użyj tnsnames.ora w Oracle SQL Developer

  5. Porównanie listy wartości z tabelą