根据值将字符串替换为列表中的另一个字符串
Replace a string with another string from a list depending on the value
假设我有这个字符串:'2015/4/21 (Tuesday)'
。我想用另一个字符串替换 'Tuesday',例如:'cat'。结果应该是:'2015/4/21 (cat)'
.
但我也希望它是动态的,如果它是 'Tuesday',那么 'cat'。如果是'Monday',那就是狗等
如何在 PostgreSQL 8.4 中执行此操作?
有一个类似的post:postgresql - replace all instances of a string within text field
但我的需要根据日期替换某些东西 动态 并且 post 替换已知值。
您应该可以使用嵌套 replace()
:
select replace(replace(str, 'Tuesday', 'cat'), 'Monday', 'dog')
如果该值不在字符串中,则不会发生任何事情。
对于几个互斥替换,嵌套替换语句是最简单和最快的方法。就 .
但是对于多个替代品来说,这并不能很好地扩展,并且存在 陷阱 :
子字符串
当字符串可以互为子串时,就变得不明确了。考虑这两个表达式:
SELECT replace((replace('2015 (Monday)', 'day', 'snake'), 'Monday', 'dog')
, replace((replace('2015 (Monday)', 'Monday', 'dog'), 'day', 'snake');
结果取决于替换顺序。你必须定义优先级。通常您会先替换较长的字符串。
连锁店
那么也有可能一个替换可能为下一个创建匹配:
SELECT replace((replace('2015 (Sunday)', 'Sun', 'Mon'), 'Monday', 'dog')
, replace((replace('2015 (Sunday)', 'Monday', 'dog'), 'Sun', 'Mon');
同样,您必须定义优先级。
每个替换都可能影响下一个。如果更换了几个以上,这就会变得模糊并且很快容易出错。如果更换可以更改,也很难维护。
正如我所说,只有星期几,嵌套 replace()
语句就可以了。这实际上不是“动态的”。如果工作日只是为了说明问题,而您实际上必须处理更多情况或真正的动态字符串,我会考虑一种不同的方法。在此相关答案中找到完整的动态解决方案:
另一个选项是递归函数:
CREATE OR REPLACE FUNCTION replace_recursive(search text, from_to text[][])
RETURNS TEXT LANGUAGE plpgsql AS $$
BEGIN
IF (array_length(from_to,1) > 1) THEN
RETURN replace_recursive(
replace(search, from_to[1][1], from_to[1][2]),
from_to[2:array_upper(from_to,1)]
);
ELSE
RETURN replace(search, from_to[1][1], from_to[1][2]);
END IF;
END;$$;
结果:
select replace_recursive('from1, from2, from3', array[['from1', 'to1'], ['from2', 'to2']]);
┌───────────────────┐
│ replace_recursive │
├───────────────────┤
│ to1, to2, from3 │
└───────────────────┘
假设我有这个字符串:'2015/4/21 (Tuesday)'
。我想用另一个字符串替换 'Tuesday',例如:'cat'。结果应该是:'2015/4/21 (cat)'
.
但我也希望它是动态的,如果它是 'Tuesday',那么 'cat'。如果是'Monday',那就是狗等
如何在 PostgreSQL 8.4 中执行此操作?
有一个类似的post:postgresql - replace all instances of a string within text field
但我的需要根据日期替换某些东西 动态 并且 post 替换已知值。
您应该可以使用嵌套 replace()
:
select replace(replace(str, 'Tuesday', 'cat'), 'Monday', 'dog')
如果该值不在字符串中,则不会发生任何事情。
对于几个互斥替换,嵌套替换语句是最简单和最快的方法。就
但是对于多个替代品来说,这并不能很好地扩展,并且存在 陷阱 :
子字符串
当字符串可以互为子串时,就变得不明确了。考虑这两个表达式:
SELECT replace((replace('2015 (Monday)', 'day', 'snake'), 'Monday', 'dog')
, replace((replace('2015 (Monday)', 'Monday', 'dog'), 'day', 'snake');
结果取决于替换顺序。你必须定义优先级。通常您会先替换较长的字符串。
连锁店
那么也有可能一个替换可能为下一个创建匹配:
SELECT replace((replace('2015 (Sunday)', 'Sun', 'Mon'), 'Monday', 'dog')
, replace((replace('2015 (Sunday)', 'Monday', 'dog'), 'Sun', 'Mon');
同样,您必须定义优先级。
每个替换都可能影响下一个。如果更换了几个以上,这就会变得模糊并且很快容易出错。如果更换可以更改,也很难维护。
正如我所说,只有星期几,嵌套 replace()
语句就可以了。这实际上不是“动态的”。如果工作日只是为了说明问题,而您实际上必须处理更多情况或真正的动态字符串,我会考虑一种不同的方法。在此相关答案中找到完整的动态解决方案:
另一个选项是递归函数:
CREATE OR REPLACE FUNCTION replace_recursive(search text, from_to text[][])
RETURNS TEXT LANGUAGE plpgsql AS $$
BEGIN
IF (array_length(from_to,1) > 1) THEN
RETURN replace_recursive(
replace(search, from_to[1][1], from_to[1][2]),
from_to[2:array_upper(from_to,1)]
);
ELSE
RETURN replace(search, from_to[1][1], from_to[1][2]);
END IF;
END;$$;
结果:
select replace_recursive('from1, from2, from3', array[['from1', 'to1'], ['from2', 'to2']]);
┌───────────────────┐
│ replace_recursive │
├───────────────────┤
│ to1, to2, from3 │
└───────────────────┘