每隔第n个字符后拆分字符串

时间:2014-01-02 21:28:37

标签: postgresql postgresql-9.1

有没有办法在PostgreSQL中的每个第n个字符之后拆分字符串?我认为regexp_split_to_array可以用来做到这一点:

select unnest(regexp_split_to_array('abcdefgh', E'...regexp here...'));

示例输入:abcdefgh

必需的输出(每隔第二个字符后分割):

ab
cd
ef
gh

必需输出(每隔3个字符后分割):

abc
def
gh

正则表达式会做什么?还有其他解决方案吗?

2 个答案:

答案 0 :(得分:9)

使用substringgenerate_series

regress=> select substring('abcdefgh' from n for 2) from generate_series(1, length( 'abcdefgh' ), 2) n;
 substring 
-----------
 ab
 cd
 ef
 gh
(4 rows)

regress=> select substring('abcdefgh' from n for 3) from generate_series(1, length( 'abcdefgh' ), 3) n;
 substring 
-----------
 abc
 def
 gh
(3 rows)

这很简单地包含在一个可内联的SQL函数中:

CREATE OR REPLACE FUNCTION string_nchars(text, integer) RETURNS setof text AS $$
SELECT substring($1 from n for $2) FROM generate_series(1, length($1), $2) n;
$$ LANGUAGE sql IMMUTABLE;

用法:

regress=> SELECT string_nchars('abcdefgh',3);
 string_nchars 
---------------
 abc
 def
 gh
(3 rows)

答案 1 :(得分:4)

您可以使用前瞻。 Lookbehind会更好,但没有实现。

仅当字符串的长度为偶数(或分割大小的倍数)时才有效,并且对于大字符串可能效率低。

select unnest(regexp_split_to_array('abcdefgh', E'(?=(..)+$)'));

如果它不是倍数,那么就像:

select reverse(unnest) from unnest(regexp_split_to_array(reverse('abcdefgh'), E'(?=(...)+$)'));

但是我可能会安装plperl然后在Perl中执行它。