YAKOVM
YAKOVM

Reputation: 10153

find all indices of the pattern in the input string

I need to find all indices of ' ' (space) and '-' (dash) in the input sting Tried to use patindex but have several problems with that :

  1. It finds only first instance of the pattern
  2. How do I build a pattern ?If I set'- ' it looks for the sequence and I wand or '-' or ' '

Upvotes: 0

Views: 57

Answers (1)

Nico
Nico

Reputation: 1197

Referring to my answer on PatternReplace, you may simply adjust the function:

CREATE FUNCTION "dbo"."GetIndices"
(
   @InputString VARCHAR(4000),
   @Pattern VARCHAR(100)
)
RETURNS @indices table
(
    pos int
)
AS
BEGIN
   DECLARE @count INT
   DECLARE @Result VARCHAR(4000) SET @Result = ''
   -- First character in a match
   DECLARE @First INT
   -- Next character to start search on
   DECLARE @Next INT SET @Next = 1
   -- Length of the total string -- 8001 if @InputString is NULL
   DECLARE @Len INT SET @Len = COALESCE(LEN(@InputString), 8001)
   -- End of a pattern
   DECLARE @EndPattern INT

   WHILE (@Next <= @Len) 
   BEGIN
      SET @First = PATINDEX('%' + @Pattern + '%', SUBSTRING(@InputString, @Next, @Len))
      --insert into @indices( pos ) values ( @first )

      IF COALESCE(@First, 0) = 0 --no match - return
      BEGIN
         SET @Result = @Result + 
            CASE --return NULL, just like REPLACE, if inputs are NULL
               WHEN  @InputString IS NULL
                     OR @Pattern IS NULL THEN NULL
               ELSE SUBSTRING(@InputString, @Next, @Len)
            END
         BREAK
      END
      ELSE
      BEGIN
         -- Concatenate characters before the match to the result
         SET @Result = @Result + SUBSTRING(@InputString, @Next, @First - 1)
         SET @Next = @Next + @First - 1
         insert into @indices( pos ) values ( @next )
         SET @EndPattern = 1
         -- Find start of end pattern range
         WHILE PATINDEX(@Pattern, SUBSTRING(@InputString, @Next, @EndPattern)) = 0
            SET @EndPattern = @EndPattern + 1
         -- Find end of pattern range
         WHILE PATINDEX(@Pattern, SUBSTRING(@InputString, @Next, @EndPattern)) > 0
               AND @Len >= (@Next + @EndPattern - 1)
            SET @EndPattern = @EndPattern + 1

         --Either at the end of the pattern or @Next + @EndPattern = @Len
         SET @Next = @Next + @EndPattern - 1
      END
   END
   RETURN
END

And use it like

SELECT * FROM "dbo"."GetIndices"( '1 1 1-1-1', '[- ]' )

See this SQL-Fiddle for demo.

Result:

POS
2
4
6
8

Upvotes: 1

Related Questions