Search code examples
sqlsql-serversql-server-2014dataexplorer

How I can replace odd patterns inside a string?


I'm in the process of creating a temporary procedure in SQL because I have a value of a table which is written in markdown, so it appear as rendered HTML in the web browser (markdown to HTML conversion).

String of the column currently look like this:

Questions about **general computing hardware and software** are off-topic for Stack Overflow unless they directly involve tools used primarily for programming. You may be able to get help on [Super User](http://superuser.com/about)

I'm currently working with bold and italic text. This mean (in the case of bold text) I will need to replace odd N times the pattern**with<b>and even times with</b>.
I saw replace() but it perform the replacement on all the patterns of the string.

So How I can replace a sub-string only if it is odd or only it is even?

Update: Some peoples wonder what schemas I'm using so just take a look here.

One more extra if you want: The markdown style hyperlink to html hyperlink doesn't look so simple.


Solution

  • Using theSTUFFfunction and a simpleWHILEloop:

    CREATE FUNCTION dbo.fn_OddEvenReplace(@text nvarchar(500), 
                                          @textToReplace nvarchar(10), 
                                          @oddText nvarchar(10), 
                                          @evenText nvarchar(500))
    RETURNS varchar(max)
    AS
    BEGIN
        DECLARE @counter tinyint
        SET @counter = 1
    
        DECLARE @switchText nvarchar(10)
        WHILE CHARINDEX(@textToReplace, @text, 1) > 0
        BEGIN
            SELECT @text = STUFF(@text, 
                        CHARINDEX(@textToReplace, @text, 1), 
                        LEN(@textToReplace), 
                        IIF(@counter%2=0,@evenText,@oddText)),
                    @counter = @counter + 1
        END
        RETURN @text
    END
    

    And you can use it like this:

    SELECT dbo.fn_OddEvenReplace(column, '**', '<b>', '</b>')
    FROM table
    

    UPDATE:

    This is re-written as an SP:

    CREATE PROC dbo.##sp_OddEvenReplace @text nvarchar(500), 
                                      @textToReplace nvarchar(10), 
                                      @oddText nvarchar(10), 
                                      @evenText nvarchar(10),
                                      @returnText nvarchar(500) output
    AS
    BEGIN
        DECLARE @counter tinyint
        SET @counter = 1
    
        DECLARE @switchText nvarchar(10)
        WHILE CHARINDEX(@textToReplace, @text, 1) > 0
        BEGIN
            SELECT @text = STUFF(@text, 
                        CHARINDEX(@textToReplace, @text, 1), 
                        LEN(@textToReplace), 
                        IIF(@counter%2=0,@evenText,@oddText)),
                    @counter = @counter + 1
        END
        SET @returnText = @text
    END
    GO
    

    And to execute:

    DECLARE @returnText nvarchar(500)
    EXEC dbo.##sp_OddEvenReplace '**a** **b** **c**', '**', '<b>', '</b>', @returnText output
    
    SELECT @returnText