我有两列,COL1和COL2。 COL1的值类似于'Birds sitting on $1 and enjoying'
,COL2的值类似于'the.location_value[/tree,\building]'
我需要使用'Birds sitting on /tree and enjoying'
即。第1列中的$1
已替换为/tree
这是逗号分隔的单词列表中的第一个单词,在COL2中用方括号[],即[/tree,\building]
我想知道postgresql中最合适的字符串函数组合来实现这一点。
答案 0 :(得分:2)
您需要首先从逗号分隔列表中提取第一个元素,为此,您可以使用split_part()
,但首先需要提取实际的值列表。这可以使用带有正则表达式的substring()
来完成:
substring(col2 from '\[(.*)\]')
将返回/tree,\building
所以完整的查询将是:
select replace(col1, '$1', split_part(substring(col2 from '\[(.*)\]'), ',', 1))
from the_table;
答案 1 :(得分:0)
这个应该适用于int
之后的任何($
)号码:
select t.*, c.col3
from t,
lateral (select string_agg(case
when o = 1 then s
else (string_to_array((select regexp_matches(t.col2, '\[(.*)\]'))[1], ','))[(select regexp_matches(s, '^\$(\d+)'))[1]::int] || substring(s from '^\$\d+(.*)')
end, '' order by o) col3
from regexp_split_to_table(t.col1, '(?=\$\d+)') with ordinality s(s, o)) c
http://rextester.com/OKZAG54145
注意:虽然它不是最有效的。它每次都会将col2
的值(在方括号中)拆分为$N
。
更新:旧版本不支持LATERAL
和WITH ORDINALITY
,但您可以尝试使用关联子查询:
select t.*, (select array_to_string(array_agg(case
when s ~ E'^\\$(\\d+)'
then (string_to_array((select regexp_matches(t.col2, E'\\[(.*)\\]'))[1], ','))[(select regexp_matches(s, E'^\\$(\\d+)'))[1]::int] || substring(s from E'^\\$\\d+(.*)')
else s
end), '') col3
from regexp_split_to_table(t.col1, E'(?=\\$\\d+)') s) col3
from t