строка regex_replace между

Я не эксперт в регулярных выражениях, и в оракуле я хочу найти строку в тексте, используя функцию оракула regexp_replace.

Строка, которую нужно найти, имеет в начале "{" и в конце "}".
Между "{" и "}" вы найдете буквы и символы "_".

Итак, если у меня есть этот текст:

это тест {HI_FRIEND} для замены

как я могу стереть строку "{HI_FRIEND}"?

Я пробовал это:

select REGEXP_REPLACE('this is a {HI_FRIEND} test to replace','*{(A-Z-)}*','') from dual

но это не работает.

Поле, содержащее текст, находится в таблице с минимум 1 миллионом записей.


person Pablo    schedule 18.01.2017    source источник
comment
что, если у меня есть строка типа 'something {123} something else'? Должен ли я удалить его или нет?   -  person Aleksej    schedule 18.01.2017
comment
В моем случае я должен удалить все символы между { и }. Ваш первый пример был идеальным, потому что вы заменили весь контент.   -  person Pablo    schedule 18.01.2017


Ответы (3)


Попробуйте это:

select REGEXP_REPLACE('this is a {HI_FRIEND} test to replace','{(.*?)}') from dual

это заменит строки, обернутые {}, независимо от их содержимого.

Ленивый оператор (?) используется, чтобы избежать проблем в случае появления более одной обернутой строки.

Например:

select REGEXP_REPLACE('this is a {HI_FRIEND} test to {HI_FRIEND} replace','{(.*)}') from dual

дает

this is a  replace

в то время как с ленивым оператором мы имеем:

select REGEXP_REPLACE('this is a {HI_FRIEND} test to {HI_FRIEND} replace','{(.*?)}') from dual

и результат:

this is a  test to  replace

Если вы хотите удалить обернутые строки только тогда, когда они состоят из заглавных букв и '_', вы можете изменить (.*?) на ([A-Z_]*?):

select REGEXP_REPLACE('this is a {HI_FRIEND} test to {123} replace','{([A-Z_]*?)}') from dual

дам:

this is a  test to {123} replace
person Aleksej    schedule 18.01.2017

Отличный инструмент для регулярных выражений, так как у меня всегда возникают эти проблемы, — это regex101.com.

Вы можете ввести свое регулярное выражение и свои образцы данных и посмотреть, что соответствует, оно также показывает простым английским языком то, что ищет регулярное выражение, а также дает ссылку на синтаксис.

Попробуйте следующее регулярное выражение {([A-Z_])*}

Он соответствует { и } дословно, но затем класс символов [A-Z_] (заглавные от A до заглавных Z или подчеркивание) * раз (от 0 до неограниченного количества раз).

person Patrick Murphy    schedule 18.01.2017

Я подозреваю, что ваша проблема не столько в использовании регулярного выражения, сколько в попытке обновить 1 миллион строк. Я бы посоветовал вам создать новую таблицу с нужными вам данными, используя опубликованный ответ REGEXP. Что-то типа...

create table new_table
as
select * from old_table
where 1=2
/

Затем у вас есть варианты ускорить это, используя прямую загрузку пути и параллелизм.

alter session enable parallel dml;

insert /*+ append */ into new_table( col1, col2, text_col, ... )
select col1, col2, REGEXP_REPLACE(...), ... )
from old_table
;

Отбросьте старую таблицу, перестройте любые индексы ограничений, соберите статистику, и все готово. Это будет намного быстрее, чем обновление.

person BobC    schedule 18.01.2017
comment
ОП не указал, что у него проблема с производительностью, и предоставленное решение предполагает, что у него есть привилегии DDL. - person Migs Isip; 18.01.2017
comment
@MigsIsip. Ты прав. Однако ОП заявил, что у него есть как минимум 1 миллион строк в таблице. Если бы проблема заключалась только в замене строки, то этот факт не имел бы значения. Итак, я предоставил то, что считаю полезной информацией как для ОП, так и для других читателей. Если это неприменимо, то это нормально; надеюсь кому-то в будущем пригодится. - person BobC; 18.01.2017