Извлечь подстроку из строки в SQL - PullRequest
6 голосов
/ 27 апреля 2011

Мне нужно извлечь текст, который окружен ***[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 ]

4 голосов
/ 27 апреля 2011

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

;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)
2 голосов
/ 27 апреля 2011

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

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

Я поиграюсь с ним и посмотрю, могу ли я добавить пример.
РЕДАКТИРОВАТЬ- Это, вероятно, требует дополнительной проверки ошибок

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
2 голосов
/ 27 апреля 2011

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

2 голосов
/ 27 апреля 2011

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

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

0 голосов
/ 27 апреля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...