文字列内の特定の文字の最初と最後の出現を見つけたい。例として、「2010-####-3434」という名前の文字列を考え、検索する文字が「#」であるとします。文字列内のハッシュの最初の出現は 6 番目の位置であり、最後の出現は 9 番目の位置です。
7 に答える
上手...
Select position('#' in '2010-####-3434');
あなたに最初を与えるでしょう。最後が必要な場合は、文字列の逆を使用してもう一度実行します。pl/pgsql文字列の逆はここにあります。
Select length('2010-####-3434') - position('#' in reverse_string('2010-####-3434')) + 1;
の場合char = '.'
、エスケープが必要です。したがって、関数は次のように記述できます。
CREATE OR REPLACE FUNCTION last_post(text,char)
RETURNS integer LANGUAGE SQL AS $$
select length($1)- length(regexp_replace($1, E'.*\\' || $2,''));
$$;
9.5+array_positions
基本的なPostgreSQL 配列関数を使用して を呼び出し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;
この純粋な SQL 関数は、1 から数えて、文字列内の char の最後の位置を提供します。見つからない場合は 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 が含まれます。
その方法はわかりませんが、正規表現は、 、のようregexp_matches
に機能し、問題を解決するための代替ルートになる可能性があります。regexp_replace
regexp_split_to_array
最後の位置をカウントする別の方法は、必要な文字に等しい区切り文字で文字列を配列に分割し、文字列全体の長さから最後の要素の文字の長さを差し引くことです。
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');