如何在PostgreSQL中的字符串中查找特定字符的第一次和最后一次出现

Posted

技术标签:

【中文标题】如何在PostgreSQL中的字符串中查找特定字符的第一次和最后一次出现【英文标题】:How to find the first and last occurrences of a specific character inside a string in PostgreSQL 【发布时间】:2010-06-03 11:56:15 【问题描述】:

我想在字符串中查找特定字符的第一次和最后一次出现。例如,考虑一个名为“2010-####-3434”的字符串,并假设要搜索的字符是“#”。字符串中第一次出现的散列在第 6 位,最后一次出现在第 9 位。

【问题讨论】:

另见:wiki.postgresql.org/wiki/Strposrev See my answer for how to do this with a 9.5+ 【参考方案1】:

嗯……

Select position('#' in '2010-####-3434');

会给你第一个。 如果你想要最后一个,只需用你的字符串的反面再次运行它。一个pl/pgsql字符串反向可以找到here。

Select length('2010-####-3434') - position('#' in reverse_string('2010-####-3434')) + 1;

【讨论】:

作为函数CREATE OR REPLACE FUNCTION last_position(text, char) RETURNS integer LANGUAGE SQL AS $$ Select length($1) - position($2 in reverse($1)) + 1; $$; 我稍微修改了@MFARID 的函数以使用更长的子字符串:CREATE OR REPLACE FUNCTION last_position(text, text) RETURNS integer LANGUAGE SQL AS $$ Select length($1) - position(reverse($2) in reverse($1)) - length($2); $$; - 所以last_position('Thomas omas omas', 'oma') 给出了 11 不是rev​​erse_string,是reverse()【参考方案2】:

char = '.' 的情况下,需要转义。所以函数可以写成:

CREATE OR REPLACE FUNCTION last_post(text,char) 
RETURNS integer LANGUAGE SQL AS $$  
select length($1)- length(regexp_replace($1, E'.*\\' || $2,''));  
$$;

【讨论】:

【参考方案3】:

我的例子:

reverse(substr(reverse(newvalue),0,strpos(reverse(newvalue),',')))
    反转所有字符串 子字符串字符串 反转结果

【讨论】:

【参考方案4】:

9.5+ array_positions

使用基本的PostgreSQL array functions,我们调用string_to_array(),然后将其提供给array_positions(),就像这样array_positions(string_to_array(str,null), c)

SELECT
  arrpos[array_lower(arrpos,1)] AS first,
  arrpos[array_upper(arrpos,1)] AS last
FROM ( VALUES
  ('2010-####-3434', '#')
) AS t(str,c)
CROSS JOIN LATERAL array_positions(string_to_array(str,null), c)
  AS arrpos;

【讨论】:

【参考方案5】:

我不知道该怎么做,但是像 regexp_matchesregexp_replaceregexp_split_to_array 这样的正则表达式函数可能是解决问题的替代方法。

【讨论】:

我认为它是一种必须填写的模板。在这种情况下,regexp_replace("#+",'ABCD') 将用 ABCD 替换 ####。 '+' 表示匹配它之前的 1 个或多个字符。这一切都在这里详细解释:developer.postgresql.org/pgdocs/postgres/… split_part(string, delimiter,occurrence) 可能有帮助【参考方案6】:

这个纯 SQL 函数将提供字符在字符串中的最后位置,从 1 开始计数。如果未找到,则返回 0 ...但是(大免责声明)如果字符是某个正则表达式元字符(.$^()[]*+ )

CREATE FUNCTION last_post(text,char) RETURNS integer AS $$ 
     select length($1)- length(regexp_replace($1, '.*' || $2,''));
$$ LANGUAGE SQL IMMUTABLE;

test=# select last_post('hi#-#-#byte','#');
 last_post
-----------
         7

test=# select last_post('hi#-#-#byte','a');
 last_post
-----------
         0

作为 rfusca 的回答,更强大的解决方案将涉及 pl/pgSQL。

【讨论】:

【参考方案7】:

另一种计算最后位置的方法是通过分隔符将字符串分割成数组,等于所需的字符,然后减去字符的长度 对于整个字符串长度的最后一个元素

CREATE FUNCTION last_pos(char, text) RETURNS INTEGER AS
$$
select length($2) - length(a.arr[array_length(a.arr,1)]) 
from (select string_to_array($2, $1) as arr) as a
$$ LANGUAGE SQL;

第一个位置比较好用

select position('#' in '2010-####-3434');

【讨论】:

以上是关于如何在PostgreSQL中的字符串中查找特定字符的第一次和最后一次出现的主要内容,如果未能解决你的问题,请参考以下文章

如何使用特定符号 C++ 查找和替换字符串中的所有字符

Postgresql中怎么把某列中的特定字符进行特定替换

如何查询我的所有视图设计以查找 SQL Server 中的特定字符串?

如何在postgresql中查找具有特定列的表

如何用函数在excel中提取特定字符后面的字符

ubuntu中在终端下如何查找具有某一特定字符串的文件?