Oracle
 sql >> база данни >  >> RDS >> Oracle

премахнете конкретна дума от низ

Поради липса на поддръжка за lookbehind/lookahead и граница на думата(\b ) в изпълнението на регулярен израз в Oracle изглежда невъзможно да се изпълнят всички изисквания в един REGEXP_REPLACE повикване. Специално за случай, посочен от Егор Скриптунов :съвпадения на шаблони, следвани едно по едно само с един разделител между тях като some some some some ... .

Без този случай е възможно да се съпоставят всички такива низове с това извикване:

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), включени в шаблона за съвпадение, те ще бъдат премахнати от изходния низ при успешно съвпадение, така че трябва да възстановим тези части, като посочим в третия 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да импортирате данни в определено таблично пространство

  2. Как да осредним интервалите от време?

  3. Изберете всички колони от таблица 1 и една колона от таблица две, която е групирана по?

  4. Свързване с Oracle Database с помощта на Sql Server Integration Services

  5. Изпълнение на динамичен sql оператор в SYS_REFCURSOR