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

Tom*_*eif 7 postgresql postgresql-9.1

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

select unnest(regexp_split_to_array('abcdefgh', E'...regexp here...'));
Run Code Online (Sandbox Code Playgroud)

输入示例: abcdefgh

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

ab
cd
ef
gh
Run Code Online (Sandbox Code Playgroud)

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

abc
def
gh
Run Code Online (Sandbox Code Playgroud)

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

Cra*_*ger 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)
Run Code Online (Sandbox Code Playgroud)

这很简单地包含在一个可内联的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;
Run Code Online (Sandbox Code Playgroud)

用法:

regress=> SELECT string_nchars('abcdefgh',3);
 string_nchars 
---------------
 abc
 def
 gh
(3 rows)
Run Code Online (Sandbox Code Playgroud)


jja*_*nes 6

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

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

select unnest(regexp_split_to_array('abcdefgh', E'(?=(..)+$)'));
Run Code Online (Sandbox Code Playgroud)

如果不是倍数,则类似:

select reverse(unnest) from unnest(regexp_split_to_array(reverse('abcdefgh'), E'(?=(...)+$)'));
Run Code Online (Sandbox Code Playgroud)

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