Как найти первое и последнее вхождения определенного символа внутри строки в PostgreSQL - PullRequest
5 голосов
/ 03 июня 2010

Я хочу найти первое и последнее вхождения определенного символа внутри строки. В качестве примера рассмотрим строку с именем «2010 - #### - 3434» и предположим, что искомый символ - «#». Первое вхождение хеша внутри строки находится в 6-й позиции, а последнее вхождение - в 9-й позиции.

Ответы [ 7 ]

15 голосов
/ 03 июня 2010

Ну ...

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

даст вам первое. Если вы хотите последнее, просто запустите это снова с обратной строкой. Обратную строку pl / pgsql можно найти здесь .

Select length('2010-####-3434') - position('#' in reverse_string('2010-####-3434')) + 1;
5 голосов
/ 10 мая 2011

В случае, когда char = '.', необходим побег. Таким образом, функция может быть написана:

CREATE OR REPLACE FUNCTION last_post(text,char) 
RETURNS integer LANGUAGE SQL AS $$  
select length($1)- length(regexp_replace($1, E'.*\\' || $2,''));  
$$;
3 голосов
/ 10 марта 2017

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;
2 голосов
/ 03 июня 2010

Эта функция чистого 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

Более надежное решение будет включать pl / pgSQL, как ответ rfusca.

2 голосов
/ 03 июня 2010

Я не знаю, как это сделать, но функции регулярных выражений, такие как regexp_matches, regexp_replace, regexp_split_to_array, могут быть альтернативным способом решения вашей проблемы

0 голосов
/ 15 октября 2018

Мой пример:

reverse(substr(reverse(newvalue),0,strpos(reverse(newvalue),',')))
  1. Обратная вся строка
  2. Подстрока
  3. Обратный результат
0 голосов
/ 02 сентября 2016

Еще один способ подсчитать последнюю позицию - разрезать строку в массив делитером, равным необходимому символу, а затем вычесть длину символов. для последнего элемента из длины всей строки

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');
...