Извлечение подстроки из строки в SQL

мне нужно извлечь текст, который окружен ***[some text] строки, как в следующем примере:

some text
some text
***[some text]
THIS SHOULD BE EXTRACTED
***[some text]
some text
some text
some text
some text
some text
***[some text]
THIS SHOULD BE EXTRACTED TOO
***[some text]
some text

выход должен быть:

THIS SHOULD BE EXTRACTED
THIS SHOULD BE EXTRACTED TOO

пробовал PATINDEX как здесь, но не мог найти способ извлечь строку.

PATINDEX('%[*][*][*][[]%]%%[*][*][*][[]%]%',@Text)

Я с нетерпением жду любых предложений.

5 ответов


не решение регулярных выражений, и я все еще новичок в SQL, поэтому не может быть оптимальным, но вы должны иметь возможность анализировать с WHILE цикл с использованием

CHARINDEX на *** затем, используя это в качестве отправной точки для
CHARINDEX до LF используйте это в качестве отправной точки для
SUBSTRING С конечной точкой, являющейся CHARINDEX следующей ***
объедините подстроку с выводом, пройдя мимо окончания *** и цикл, чтобы найти следующий один.

я поиграю с ним и посмотрю, могу ли я добавить пример.
EDIT-это, вероятно, нуждается в дополнительной проверке ошибок

declare @inText nvarchar(2000) = 'some text 
some text 
***[some text] 
THIS SHOULD BE EXTRACTED 
***[some text] 
some text 
some text 
some text 
some text 
some text 
***[some text] 
THIS SHOULD BE EXTRACTED TOO 
***[some text] 
some text '

declare @delim1 nvarchar(50) = '***'
declare @delim2 char = char(10)
declare @output nvarchar(1000) = ''
declare @position int
declare @positionEnd int

set @position = CHARINDEX(@delim1,@inText)
while (@position != 0 and @position is not null)
BEGIN
  set @position = CHARINDEX(@delim2,@inText,@position)
  set @positionEnd = CHARINDEX(@delim1,@inText,@position)
  set @output = @output + SUBSTRING(@inText,@position,@positionEnd-@position)
  set @position = CHARINDEX(@delim1,@inText,@positionEnd+LEN(@delim1))
END
select @output

для несколько более легкого случая, поднятого в комментариях, вы можете сделать

;WITH T(C) AS
(
 SELECT '
    some text
    some text
    ***[some text 1]
    THIS SHOULD BE EXTRACTED
    ***[some text 2]
    some text
    some text
    some text
    some text
    some text
    ***[some text 1]
    THIS SHOULD BE EXTRACTED TOO
    ***[some text 2]
    some text'
)
SELECT col.value('.','varchar(max)')
FROM T
CROSS APPLY (SELECT CAST('<a keep="false">' + 
                        REPLACE(
                            REPLACE(C,'***[some text 2]','</a><a keep="false">'),
                        '***[some text 1]','</a><a keep="true">') + 
                    '</a>' AS xml) as xcol) x
CROSS APPLY xcol.nodes('/a[@keep="true"]') tab(col)

вы можете найти в моем блоге: http://sql-tricks.blogspot.com/2011/04/extract-strings-with-delimiters.html Это чистое решение без дополнительной модификации, только последовательности разделителей должны быть decalred.


Я могу ошибаться, но я не думаю, что есть чистый способ сделать это непосредственно в SQL. Я бы использовал хранимая процедура CLR и используйте регулярные выражения из C# или вашего языка .NET по выбору.

посмотреть в этой статье (или в этой статье) для соответствующего примера с использованием регулярных выражений.


Я считаю, что вы можете использовать xp_regex_match как описано вhttp://www.codeproject.com/KB/mcpp/xpregex.aspx?q=use + sql + функция + to + синтаксический анализ + текст для анализа поля nvarchar. Некоторое время назад я написал нечто подобное.