Regex Replace, который содержит пустой массив по умолчанию - PullRequest
1 голос
/ 15 апреля 2020

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

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

Пока у меня есть это:

create or replace function remove_words(name text, words_to_remove text[] default '{}'::text[]) returns text as
$$
    select regexp_replace(name,(select '(' || string_agg(r,'|') || ')' from unnest(words_to_remove) r),'','gi');
$$ language sql immutable parallel safe;

В минуту, если я вызову функцию с обоими параметрами, похоже, он работает как ожидалось:

select remove_words('red orange blue green', '{black, brown, green, orange}');

 remove_words 
---------------
 red blue 

Однако, если я не пропущу второй параметр, возвращаемый текст будет пустым, в отличие от исходного значения:

select remove_words('red orange blue green');
 remove_words 
---------------

Кто-нибудь может посоветовать, как мне это сделать?

1 Ответ

1 голос
/ 15 апреля 2020

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

create or replace function remove_words(
    name text, 
    words_to_remove text[] default '{}'::text[]
) returns text as
$$
    select string_agg(word, ' ')
    from unnest(string_to_array(name, ' ')) n(word)
    where not n.word = any (words_to_remove)
$$ language sql immutable parallel safe;

Вы также можете использовать regexp_split_to_table(), чтобы разделить строка:

create or replace function remove_words2(
    name text, 
    words_to_remove text[] default '{}'::text[]
) returns text as
$$
    select string_agg(word, ' ')
    from regexp_split_to_table(name, ' ') n(word)
    where not n.word = any (words_to_remove)
$$ language sql immutable parallel safe;

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

Демонстрация на DB Fiddle :

select remove_words('red orange blue green', '{black, brown, green, orange}');

| remove_words |
| ------------ |
| red blue     |


select remove_words('red orange blue green');

| remove_words          |
| --------------------- |
| red orange blue green |


select remove_words2('red orange blue green', '{black, brown, green, orange}');

| remove_words2 |
| ------------- |
| red blue      |


select remove_words2('red orange blue green');

| remove_words2         |
| --------------------- |
| red orange blue green |
...