1

I have a string of this type:

URL/X/help?

X stands for chars like: a,b,c etc... Only one chars in that place. The length of URL is unknown it can be: www.website.com , www.website.co.uk , www.website.info etc...

I want to find out the position of /X/ in the string but only if X is: s,b,t

/X/ - appear once and only once in the string.

Something like:

select position ('/s/' or '/b/' or '/t/' in URL)

however this is not PostgreSQL syntax.

Is there a way to write this query except doing :

select position ('/s/' in URL) + 
select position ('/b/' in URL) +
select position ('/t/' in URL)

EDIT: There are no complex cases. No need to worry about /s/s or /b//s/ or /s/g/ or /s/..../s/ etc... Just the simple case I presented. It also guaranteed that /CHAR/ will appear exactly once but the char is unknown.

5
  • I think you got the best solution. Commented Aug 20, 2018 at 6:33
  • @LaurenzAlbe isn't there a way to use reg expressions to handle this? Commented Aug 20, 2018 at 6:39
  • @Programmer120 what's your sample input and expected output, please edit question and fill this in. Include the most complicated combination of data you can think of to this sample so that it covers everything you want. Commented Aug 20, 2018 at 6:43
  • @Programmer120 Even if there is a way to do this with regular expressions (I can't think of one), it would certainly be slower than your idea. Regular expressions use a lot of CPU. Commented Aug 20, 2018 at 6:48
  • @KamilG. There is no complected case. This is my whole example. /CHAR/ appear once and only once. There can't be a mix. Commented Aug 20, 2018 at 6:52

1 Answer 1

3

Since you wanted to know if there's a way to do this using regular expression, here's one:

select 
  coalesce(nullif(length(regexp_replace(url, '\/[sbt]\/.*', '')), length(url))+1, 0) as pos
from ( select 'www.webexample.com/s/help?' as url union all
       select 'www.webexample.com/d/help?' as url ) t;

Outputs:

| pos |
+-----+
| 19  |
| 0   |

How it works?

  1. Using regexp_replace find & replace string part starting from /s/, /b/ or /t/ to the end of string with blank character ''
  2. Calculate length of the result to see the position of last character before /
  3. Apply nullif function which returns NULL if length of an url after string replacement equals length of the original url
  4. Add +1 to get the position of slash right before any of characters from class: [sbt]
  5. Apply coalesce function which translates NULL values to 0

Thanks @Abelisto for input

Sign up to request clarification or add additional context in comments.

6 Comments

Works greate except once case... when the [sbt] doesn't exist for example: select length(regexp_replace(url, '\/[sbt]\/.*', ''))+1 from ( select 'www.webexample.com/d/help?' as url ) t it should give 0 in this case. Other than that works awesome
@Programmer120 nullif(length(regexp_replace(url, '\/[sbt]\/.*', '')), length(url))+1 will return NULL if substring not found.
Adjusted my answer with a possible solution.
@KamilG. Why not just position('|!|' in regexp_replace(url, '\/[sbt]\/.*', '|!|')) ?
@Abelisto thanks for pointing that out. I overcomplicated things. nullif + coalesce will do the work.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.