【问题标题】:Split string after every nth character在每第 n 个字符后拆分字符串
【发布时间】:2014-01-02 21:28:36
【问题描述】:
有没有办法在 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
什么正则表达式可以做到这一点?有没有其他解决办法?
【问题讨论】:
标签:
postgresql
postgresql-9.1
【解决方案1】:
使用substring 和generate_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)
【解决方案2】:
您可以使用前瞻。 Lookbehind 会更好,但没有实现。
这仅适用于字符串长度为偶数(或拆分大小的倍数)的情况,并且对于大字符串可能效率低下。
select unnest(regexp_split_to_array('abcdefgh', E'(?=(..)+$)'));
如果不是倍数,则类似:
select reverse(unnest) from unnest(regexp_split_to_array(reverse('abcdefgh'), E'(?=(...)+$)'));
但我可能会安装 plperl,然后在 Perl 中进行。