SQL Сервер Регулярное выражение для разбора текста в сложном формате - PullRequest
0 голосов
/ 11 апреля 2020

У меня есть таблица, подобная следующей, в SQL Server 2016:

CREATE TABLE #SampleValues (TextID INT, Comment VARCHAR(MAX) )
INSERT INTO #SampleValues (TextID, Comment)
SELECT 1, 'user 1 has done crosswalk 99220 to 99215 and submitted' UNION
SELECT 2, 'got update that crossedwalked 99308 to 99221' UNION
SELECT 3, '99255 CROSSWALKED TO 99223' UNION
SELECT 4, 'proposed crosswalk 99219 to 99214 and clean' UNION
SELECT 5, 'tested and confiimed cross walked code from 99223 to 99255' UNION
SELECT 6, 'User 2 Crosswalked codes change 99254 to 99222' UNION
SELECT 7, 'User3cross walked code from 99232 to 99307'
SELECT 8, 'Updated to 99307'

Ожидаемый результат будет похож на скриншот ниже.
enter image description here

Ожидается, что значения комментариев будут в одном из следующих форматов (без учета регистра). Если он не соответствует этим форматам, ожидаемый результат будет NULL

<some_pre-text>crossedwalked Number1 to Number2<some_post-text>
<some_pre-text>crosswalk Number1 to Number2<some_post-text>
<some_pre-text>crosswalk Number1 to Number2<some_post-text>
<some_pre-text>Crosswalked codes change Number1 to Number2<some_post-text>
<some_pre-text>cross walked code from Number1 to Number2<some_post-text>
<some_pre-text>cross walked code from Number1 to Number2<some_post-text>
<some_pre-text>Number1 CROSSWALKED TO Number2<some_post-text>

Я нашел несколько простых примеров регулярных выражений - но не нашел примеров того, как достичь этих сложных форматов. Есть мысли о том, как сделать это сложное регулярное выражение?

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

попробуйте следующее:

select comment,  NULLIF(SUBSTRING(comment
                            , PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', comment)
                                , CASE WHEN CHARINDEX(' ', comment, patindex('%[0-9][0-9][0-9][0-9][0-9]%', Comment)) - PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', comment) < 0 THEN 0
                                    ELSE CHARINDEX(' ', comment, patindex('%[0-9][0-9][0-9][0-9][0-9]%', Comment)) - PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', comment) END ), '')
+ ' to ' + NULLIF(REVERSE(substring(REVERSE(comment)
                        , patindex('%[0-9][0-9][0-9][0-9][0-9]%', REVERSE(comment))
                            , CASE WHEN CHARINDEX(' ', REVERSE(comment), patindex('%[0-9][0-9][0-9][0-9][0-9]%', REVERSE(Comment))) - patindex('%[0-9][0-9][0-9][0-9][0-9]%', REVERSE(comment)) < 0     THEN 0 ELSE CHARINDEX(' ', REVERSE(comment), patindex('%[0-9][0-9][0-9][0-9][0-9]%', REVERSE(Comment))) - patindex('%[0-9][0-9][0-9][0-9][0-9]%', REVERSE(comment))  END )),'') AS Extracted

Шаги:

  1. Извлеките начальную позицию любого числа с 5 или более цифрами

  2. Найти следующий пробел из этой позиции (из шага 1)

  3. Повторите два вышеупомянутых шага в обратной строке

  4. Объедините по мере необходимости

Пожалуйста, найдите дб <> скрипку здесь .

1 голос
/ 11 апреля 2020

SQL Сервер довольно плохо обрабатывает строки. Если я предполагаю, что to всегда перед вторым числом, как в ваших примерах, то:

select *,
       left(v.pat, charindex(' to ', v.pat) + 9)
from SampleValues t cross apply
     (values (case when comment like '%[0-9][0-9][0-9][0-9][0-9]%to%[0-9][0-9][0-9][0-9][0-9]%'
                   then stuff(comment,
                              1,
                              patindex('%[0-9][0-9][0-9][0-9][0-9]%to%[0-9][0-9][0-9][0-9][0-9]%', comment) - 1,
                              ''
                             )
              end)
     ) v(pat)

Здесь - это db <> скрипка.

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