views:

140

answers:

3

I want to find the first and the last occurrences of a specific character inside a string. As an example, consider a string named "2010-####-3434", and suppose the character to be searched for is "#". The first occurrence of hash inside the string is at 6-th position, and the last occurrence is at 9-th position.

+1  A: 

I do not know how to do that, but the regular expression functions like regexp_matches, regexp_replace, regexp_split_to_array may be an alternative route to soling your problem

Peter Tillemans
I couldn't figure out the regexp to match that character sequence.....could you help me out a bit ?
Night Shade
I assume it is kind of a template which must be filled in. in that case regexp_replace("#+",'ABCD') will replace the #### with ABCD. The '+' sign signifies to match 1 or more of the character before it. It is all explained in detail here : http://developer.postgresql.org/pgdocs/postgres/functions-matching.html#FUNCTIONS-POSIX-REGEXP
Peter Tillemans
Thank you very much
Night Shade
+3  A: 

Well...

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

will give you the first. If you want the last, just run that again with the reverse of your string. A pl/pgsql string reverse can be found here.

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

This pure SQL function will provide the last position of a char inside the string, counting from 1. It returns 0 if not found ... But (big disclaimer) it breaks if the character is some regex metacharacter ( .$^()[]*+ )

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

A more robust solution would involve pl/pgSQL, as rfusca's answer.

leonbloy