Условное regexp_replace Oracle / PLSQL

Я пытаюсь выполнить условную замену в одном операторе regexp_replace.

Например, если у меня есть строка 'Dog Cat Donkey', я хотел бы иметь возможность заменить 'Dog' на 'BigDog', 'Cat' на 'SmallCat' и 'Donkey 'на 'MediumDonkey', чтобы получить следующее:

'BigDog SmallCat MediumDonkey'

Я могу сделать это там, где все имеют префикс со словом Big, но не могу заменить его условно.

У меня сейчас есть это

select regexp_replace('Dog Cat Donkey', '(Cat)|(Dog)|(Donkey)', ' Big\1\2\3')
from dual 

но, конечно, это возвращает только BigDog BigCat BigDonkey.

Я понимаю, что это не лучший способ сделать это, но возможно ли это?

Вы можете только условно заменить в регулярном выражении Boost. Ни в коем случае с регулярным выражением Oracle.

Wiktor Stribiżew 15.06.2018 18:58

Разве вы не можете использовать несколько выражений, таких как Bigs Dog|Wolf|Dingo, Smalls, например Cat|Persian, и Mediums Donkey|Horse? Если вы не можете выполнить обратный вызов, значит, это невозможно сделать сразу. Конечно, вы также можете добавить границы вокруг чередований, например, слово \b(list)\b и пробел (?<!\S)(list)(?!\S), если это необходимо.

user557597 15.06.2018 19:46
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
2
863
3

Ответы 3

Вы не думали просто сделать несколько replace()?

select replace(replace(replace(str, 'Dog', 'BigDog'), 'Cat', 'SmallCat'), 'Donkey', 'MediumDonkey')

Я понимаю, что regexp_replace() действительно мощный. И он мог бы это сделать. Но я не уверен, что это лучшее решение с точки зрения выражения того, что вы делаете.

Я полностью согласен! Это разрешить офисный аргумент о возможности. :)

Squashy Josh 15.06.2018 18:59

Если одно слово является подстрокой другого, с этим подходом могут возникнуть проблемы.

Wiktor Stribiżew 15.06.2018 19:03

@ WiktorStribiżew. . . То же самое можно сказать и об исходном регулярном выражении OP.

Gordon Linoff 15.06.2018 19:37

@GordonLinoff Нет, потому что регулярное выражение обрабатывает строку только один раз.

Wiktor Stribiżew 15.06.2018 19:45

Запрос -

select listagg(final_str,' ') within group (order by sort_str) as output from (
SELECT 
    CASE LST
        WHEN 'Dog' THEN 'BigDog'
        WHEN 'Cat' THEN 'SmallCat'
        WHEN 'Donkey' THEN 'MediumDonkey'
    END AS final_str,
    CASE LST
        WHEN 'Dog' THEN 1
        WHEN 'Cat' THEN 2
        WHEN 'Donkey' THEN 3
    END AS sort_str
from (
SELECT
    trim(REGEXP_SUBSTR('Dog Cat Donkey', '(\S*)(\s*)', 1, LEVEL)) AS LST
FROM
    DUAL
CONNECT BY
    REGEXP_SUBSTR('Dog Cat Donkey', '(\S*)(\s*)', 1, LEVEL) IS NOT NULL
    ));

Выход -

BigDog SmallCat MediumDonkey

Для условной замены через REGEX_REPLACE?

Теперь вы можете сделать это, повторяя это для каждой другой строки замены.

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

И как указал Гордон Линофф. На самом деле вам не нужен REGEX_REPLACE, когда обычного REPLACE достаточно для сопоставления одного слова.

select regexp_replace(
         regexp_replace(
           regexp_replace( str, 
              '(Dog|Snoopy)', 'Big\1')
            ,'(Cat|Feline)', 'Small\1')
           ,'(Donkey|Ass)', 'Medium\1')
from (select 'You Ass, that is not a Dog, but a Cat on a Donkey.' as str from dual);

Возврат:

You MediumAss, that is not a BigDog, but a SmallCat on a MediumDonkey.

Однако обратите внимание, что при использовании канала в регулярном выражении порядок имеет значение. Поэтому, если некоторые слова начинаются одинаково, лучше расположить их в порядке убывания длины. Пример:

select 
regexp_replace(str, '(foo|foobar)', '[\1]') as foo_foobar,
regexp_replace(str, '(foobar|foo)', '[\1]') as foobar_foo
from (select 'foo foobar' as str from dual);

Возврат:

FOO_FOOBAR       FOOBAR_FOO
---------------  ---------------
[foo] [foo]bar   [foo] [foobar]

Другие вопросы по теме