首页 > 解决方案 > 包含默认空数组的正则表达式替换

问题描述

我正在尝试创建一个函数,该函数接受一个文本参数和一个文本参数数组,当没有传递第二个参数时,该数组默认为一个空数组。

然后,我想替换 text 参数中也出现在要删除的文本数组中的任何单词。如果这个数组是空的,我不想删除任何东西。

到目前为止,我有这个:

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

谁能建议我如何使这项工作?

标签: sqlarraysregexpostgresqlsql-function

解决方案


我会采取相反的方法,即:将字符串转换为单词表,然后消除属于数组的单词。

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 |

推荐阅读