0

I want to know a flexible way to extract the string between two '-'. The issue is that '-' may or may not exist in the source string. I have the following code which works fine when '-' exists twice in the source string, marking the start and end of the extracted string. But it throws an error "Invalid length parameter passed to the LEFT or SUBSTRING function" when there is only one '-' or none at all or if the string is blank. Can someone please help? Thanks

  declare @string varchar(100) = 'BLAH90-ExtractThis-WOW'
  SELECT SUBSTRING(@string,CHARINDEX('-',@string)+1, CHARINDEX('-',@string,CHARINDEX('-',@string)+1) -CHARINDEX('-',@string)-1) as My_String

Desired Output: ExtractThis

If there is one dash only e.g. 'BLAH90-ExtractThisWOW' then the output should be everything after the first dash i.e. ExtractThisWOW. If there are no dashes then the string will have a blank space instead e.g. 'BLAH90 ExtractThisWOW' and should return everything after the blank space i.e. ExtractThisWOW.

5
  • What do you expect if there's only one dash, or no dashes? Commented Mar 4, 2020 at 16:34
  • Add if statement and check if charindex('-',@string)>0, then only execute Commented Mar 4, 2020 at 16:44
  • @Jack good question - I've updated the original post with these scenarios. Commented Mar 4, 2020 at 17:09
  • @Python_newbieash have a look at my answer ... it has gotten complicated, but it should cover the cases Commented Mar 4, 2020 at 17:23
  • What about matching /(?<=')[^-]*|(?<= ).*/, (?<=...) being a positive lookbehind? Commented Mar 4, 2020 at 18:04

3 Answers 3

2

Take your existing code:

declare @string varchar(100) = 'BLAH90-ExtractThis-WOW'
SELECT SUBSTRING(@string,CHARINDEX('-',@string)+1, CHARINDEX('-',@string,CHARINDEX('-',@string)+1) -CHARINDEX('-',@string)-1) as My_String

insert one line, like so:

declare @string varchar(100) = 'BLAH90-ExtractThis-WOW'
SET @string = @string + '--'
SELECT SUBSTRING(@string,CHARINDEX('-',@string)+1, CHARINDEX('-',@string,CHARINDEX('-',@string)+1) -CHARINDEX('-',@string)-1) as My_String

and you're done. (If NULL, you will get NULL returned. Also, this will return all data based on the FIRST dash found in the string, regardless of however many dashes are in the string.)

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

Comments

1

You can try something like this.

When there is no dash, it starts at the space if there is one or take the whole string if not. Then I look if there is only one dash or 2

declare @string varchar(100) = 'BLAH90-ExtractThis-WOW'
declare @dash_pos integer = CHARINDEX('-',@string)

SELECT CASE 
WHEN @dash_pos = 0 THEN 
       RIGHT(@string,LEN(@string)-CHARINDEX(' ',@string))
ELSE (
    CASE 
        WHEN @dash_pos = LEN(@string)-CHARINDEX('-',REVERSE(@string))+1 
        THEN RIGHT(@string,LEN(@string)-@dash_pos)
    ELSE SUBSTRING(@string,@dash_pos+1, CHARINDEX('-',@string,@dash_pos+1) - 
                                                     @dash_pos -1) 
    END
) 
END as My_String  

1 Comment

Thanks @Fabian TheSolution! This works like a charm!
1

Try this. If there are two dashes, it'll take what is inside. If there is only one or none, it'll keep the original string.

  declare @string varchar(100) = 'BLAH-90ExtractThisWOW'
  declare @dash_index1 int = case when @string like '%-%' then CHARINDEX('-', @string) else -1 end
  declare @dash_index2 int = case when @string like '%-%'then len(@string) - CHARINDEX('-', reverse(@string)) + 1 else -1 end

  SELECT case 
         when @dash_index1 <> @dash_index2 then SUBSTRING(@string,CHARINDEX('-',@string)+1, CHARINDEX('-',@string,CHARINDEX('-',@string)+1) -CHARINDEX('-',@string)-1) 
         else @string end
         as My_String

1 Comment

Sorry about that. try it now. I accidentally erased the '-' when formatting the sql

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.